Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4641 → Rev 4647

/branches/arm/kernel/kernel.config
File deleted
/branches/arm/kernel/arch/ppc64/_link.ld.in
File deleted
/branches/arm/kernel/arch/ppc64/include/elf.h
File deleted
/branches/arm/kernel/arch/ppc64/include/memstr.h
File deleted
/branches/arm/kernel/arch/ppc64/include/arg.h
File deleted
/branches/arm/kernel/arch/ppc64/include/atomic.h
File deleted
/branches/arm/kernel/arch/ppc64/include/arch.h
File deleted
/branches/arm/kernel/arch/ppc64/include/proc/thread.h
File deleted
/branches/arm/kernel/arch/ppc64/include/proc/task.h
File deleted
/branches/arm/kernel/arch/ppc64/include/boot/boot.h
File deleted
/branches/arm/kernel/arch/ppc64/include/faddr.h
File deleted
/branches/arm/kernel/arch/ppc64/include/asm.h
File deleted
/branches/arm/kernel/arch/ppc64/include/mm/page.h
File deleted
/branches/arm/kernel/arch/ppc64/include/mm/asid.h
File deleted
/branches/arm/kernel/arch/ppc64/include/mm/tlb.h
File deleted
/branches/arm/kernel/arch/ppc64/include/mm/as.h
File deleted
/branches/arm/kernel/arch/ppc64/include/mm/frame.h
File deleted
/branches/arm/kernel/arch/ppc64/include/context.h
File deleted
/branches/arm/kernel/arch/ppc64/include/debug.h
File deleted
/branches/arm/kernel/arch/ppc64/include/barrier.h
File deleted
/branches/arm/kernel/arch/ppc64/include/cpu.h
File deleted
/branches/arm/kernel/arch/ppc64/include/drivers/pic.h
File deleted
/branches/arm/kernel/arch/ppc64/include/asm/regname.h
File deleted
/branches/arm/kernel/arch/ppc64/include/context_offset.h
File deleted
/branches/arm/kernel/arch/ppc64/include/interrupt.h
File deleted
/branches/arm/kernel/arch/ppc64/include/fpu_context.h
File deleted
/branches/arm/kernel/arch/ppc64/include/exception.h
File deleted
/branches/arm/kernel/arch/ppc64/include/cycle.h
File deleted
/branches/arm/kernel/arch/ppc64/include/byteorder.h
File deleted
/branches/arm/kernel/arch/ppc64/include/cpuid.h
File deleted
/branches/arm/kernel/arch/ppc64/include/types.h
File deleted
/branches/arm/kernel/arch/ppc64/Makefile.inc
File deleted
/branches/arm/kernel/arch/ppc64/src/asm.S
File deleted
/branches/arm/kernel/arch/ppc64/src/proc/scheduler.c
File deleted
/branches/arm/kernel/arch/ppc64/src/boot/boot.S
File deleted
/branches/arm/kernel/arch/ppc64/src/context.S
File deleted
/branches/arm/kernel/arch/ppc64/src/debug/panic.s
File deleted
/branches/arm/kernel/arch/ppc64/src/cpu/cpu.c
File deleted
/branches/arm/kernel/arch/ppc64/src/mm/frame.c
File deleted
/branches/arm/kernel/arch/ppc64/src/mm/page.c
File deleted
/branches/arm/kernel/arch/ppc64/src/mm/tlb.c
File deleted
/branches/arm/kernel/arch/ppc64/src/mm/as.c
File deleted
/branches/arm/kernel/arch/ppc64/src/dummy.s
File deleted
/branches/arm/kernel/arch/ppc64/src/interrupt.c
File deleted
/branches/arm/kernel/arch/ppc64/src/ppc64.c
File deleted
/branches/arm/kernel/arch/ppc64/src/drivers/pic.c
File deleted
/branches/arm/kernel/arch/ppc64/src/exception.S
File deleted
/branches/arm/kernel/arch/ppc64/src/fpu_context.S
File deleted
/branches/arm/kernel/arch/ppc64/src/ddi/ddi.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/atomic.S
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/interrupt.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/drivers/xconsole.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/fpu_context.c
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/asm.S
File deleted
/branches/arm/kernel/arch/ia32xen/src/context.S
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/debug
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/cpu
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/ia32xen.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/bios
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/pm.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/delay.s
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/smp/mps.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/smp/smp.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/smp/ipi.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/smp/apic.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/ddi
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/boot/boot.S
File deleted
/branches/arm/kernel/arch/ia32xen/src/proc/scheduler.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/proc/task.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/proc/thread.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/debugger.c
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/src/mm/frame.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/mm/page.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/mm/tlb.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/mm/as.c
File deleted
/branches/arm/kernel/arch/ia32xen/src/userspace.c
File deleted
/branches/arm/kernel/arch/ia32xen/_link.ld.in
File deleted
/branches/arm/kernel/arch/ia32xen/include/fpu_context.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/cycle.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/byteorder.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/types.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/cpuid.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/elf.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/bios
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/memstr.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/smp
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/arg.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/ddi
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/pm.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/atomic.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/arch.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/proc
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/faddr.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/asm.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/hypercall.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/mm/frame.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/mm/page.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/mm/asid.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/mm/tlb.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/mm/as.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/debugger.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/context.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/barrier.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/debug.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/cpu.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/drivers/xconsole.h
File deleted
/branches/arm/kernel/arch/ia32xen/include/context_offset.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/include/interrupt.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/ia32xen/Makefile.inc
File deleted
/branches/arm/kernel/arch/sparc64/src/asm.S
225,10 → 225,15
 
.global memsetb
memsetb:
b _memsetb
ba %xcc, _memsetb
nop
 
.global memsetw
memsetw:
ba %xcc, _memsetw
nop
 
 
.macro WRITE_ALTERNATE_REGISTER reg, bit
rdpr %pstate, %g1 ! save PSTATE.PEF
wrpr %g0, (\bit | PSTATE_PRIV_BIT), %pstate
272,7 → 277,7
*/
.global switch_to_userspace
switch_to_userspace:
save %o1, -STACK_WINDOW_SAVE_AREA_SIZE, %sp
save %o1, -(STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE), %sp
flushw
wrpr %g0, 0, %cleanwin ! avoid information leak
 
/branches/arm/kernel/arch/sparc64/src/smp/smp.c
35,6 → 35,7
#include <smp/smp.h>
#include <genarch/ofw/ofw_tree.h>
#include <cpu.h>
#include <arch/cpu_family.h>
#include <arch/cpu.h>
#include <arch.h>
#include <config.h>
43,6 → 44,7
#include <synch/synch.h>
#include <synch/waitq.h>
#include <print.h>
#include <arch/cpu_node.h>
 
/**
* This global variable is used to pick-up application processors
59,17 → 61,57
void smp_init(void)
{
ofw_tree_node_t *node;
count_t cnt = 0;
size_t cnt = 0;
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu");
while (node) {
cnt++;
node = ofw_tree_find_peer_by_device_type(node, "cpu");
if (is_us() || is_us_iii()) {
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
while (node) {
cnt++;
node = ofw_tree_find_peer_by_device_type(node, "cpu");
}
} else if (is_us_iv()) {
node = ofw_tree_find_child(cpus_parent(), "cmp");
while (node) {
cnt += 2;
node = ofw_tree_find_peer_by_name(node, "cmp");
}
}
config.cpu_count = max(1, cnt);
}
 
/**
* Wakes up the CPU which is represented by the "node" OFW tree node.
* If "node" represents the current CPU, calling the function has
* no effect.
*/
static void wakeup_cpu(ofw_tree_node_t *node)
{
uint32_t mid;
ofw_tree_property_t *prop;
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */
prop = ofw_tree_getprop(node, "upa-portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "cpuid");
if (!prop || prop->value == NULL)
return;
mid = *((uint32_t *) prop->value);
if (CPU->arch.mid == mid)
return;
 
waking_up_mid = mid;
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) ==
ESYNCH_TIMEOUT)
printf("%s: waiting for processor (mid = %" PRIu32
") timed out\n", __func__, mid);
}
 
/** Wake application processors up. */
void kmp(void *arg)
{
76,31 → 118,18
ofw_tree_node_t *node;
int i;
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu");
for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) {
uint32_t mid;
ofw_tree_property_t *prop;
prop = ofw_tree_getprop(node, "upa-portid");
if (!prop || !prop->value)
continue;
mid = *((uint32_t *) prop->value);
if (CPU->arch.mid == mid) {
/*
* Skip the current CPU.
*/
continue;
if (is_us() || is_us_iii()) {
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
for (i = 0; node;
node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++)
wakeup_cpu(node);
} else if (is_us_iv()) {
node = ofw_tree_find_child(cpus_parent(), "cmp");
while (node) {
wakeup_cpu(ofw_tree_find_child(node, "cpu@0"));
wakeup_cpu(ofw_tree_find_child(node, "cpu@1"));
node = ofw_tree_find_peer_by_name(node, "cmp");
}
 
/*
* Processor with ID == mid can proceed with its initialization.
*/
waking_up_mid = mid;
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT)
printf("%s: waiting for processor (mid = %" PRIu32 ") timed out\n",
__func__, mid);
}
}
 
/branches/arm/kernel/arch/sparc64/src/smp/ipi.c
46,6 → 46,33
#include <time/delay.h>
#include <panic.h>
 
/** Set the contents of the outgoing interrupt vector data.
*
* The first data item (data 0) will be set to the value of func, the
* rest of the vector will contain zeros.
*
* This is a helper function used from within the cross_call function.
*
* @param func value the first data item of the vector will be set to
*/
static inline void set_intr_w_data(void (* func)(void))
{
#if defined (US)
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_0, (uintptr_t) func);
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_1, 0);
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_2, 0);
#elif defined (US3)
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_0, (uintptr_t) func);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_1, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_2, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_3, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_4, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_5, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_6, 0);
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_7, 0);
#endif
}
 
/** Invoke function on another processor.
*
* Currently, only functions without arguments are supported.
71,16 → 98,15
status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
if (status & INTR_DISPATCH_STATUS_BUSY)
panic("Interrupt Dispatch Status busy bit set\n");
panic("Interrupt Dispatch Status busy bit set.");
ASSERT(!(pstate_read() & PSTATE_IE_BIT));
do {
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_0,
(uintptr_t) func);
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_1, 0);
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_2, 0);
asi_u64_write(ASI_UDB_INTR_W,
set_intr_w_data(func);
asi_u64_write(ASI_INTR_W,
(mid << INTR_VEC_DISPATCH_MID_SHIFT) |
ASI_UDB_INTR_W_DISPATCH, 0);
VA_INTR_W_DISPATCH, 0);
membar();
125,7 → 151,7
func = tlb_shootdown_ipi_recv;
break;
default:
panic("Unknown IPI (%d).\n", ipi);
panic("Unknown IPI (%d).", ipi);
break;
}
/branches/arm/kernel/arch/sparc64/src/mm/tlb.c
54,14 → 54,13
#include <arch/mm/tsb.h>
#endif
 
static void dtlb_pte_copy(pte_t *t, index_t index, bool ro);
static void itlb_pte_copy(pte_t *t, index_t index);
static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
const char *str);
static void do_fast_data_access_mmu_miss_fault(istate_t *istate,
tlb_tag_access_reg_t tag, const char *str);
static void do_fast_data_access_protection_fault(istate_t *istate,
tlb_tag_access_reg_t tag, const char *str);
static void dtlb_pte_copy(pte_t *, size_t, bool);
static void itlb_pte_copy(pte_t *, size_t);
static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *);
static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t,
const char *);
static void do_fast_data_access_protection_fault(istate_t *,
tlb_tag_access_reg_t, const char *);
 
char *context_encoding[] = {
"Primary",
86,11 → 85,11
 
/** Insert privileged mapping into DMMU TLB.
*
* @param page Virtual page address.
* @param frame Physical frame address.
* @param pagesize Page size.
* @param locked True for permanent mappings, false otherwise.
* @param cacheable True if the mapping is cacheable, false otherwise.
* @param page Virtual page address.
* @param frame Physical frame address.
* @param pagesize Page size.
* @param locked True for permanent mappings, false otherwise.
* @param cacheable True if the mapping is cacheable, false otherwise.
*/
void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize,
bool locked, bool cacheable)
103,7 → 102,7
pg.address = page;
fr.address = frame;
 
tag.value = ASID_KERNEL;
tag.context = ASID_KERNEL;
tag.vpn = pg.vpn;
 
dtlb_tag_access_write(tag.value);
126,12 → 125,12
 
/** Copy PTE to TLB.
*
* @param t Page Table Entry to be copied.
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
* @param ro If true, the entry will be created read-only, regardless of its
* w field.
* @param t Page Table Entry to be copied.
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
* @param ro If true, the entry will be created read-only, regardless
* of its w field.
*/
void dtlb_pte_copy(pte_t *t, index_t index, bool ro)
void dtlb_pte_copy(pte_t *t, size_t index, bool ro)
{
tlb_tag_access_reg_t tag;
tlb_data_t data;
165,10 → 164,10
 
/** Copy PTE to ITLB.
*
* @param t Page Table Entry to be copied.
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
* @param t Page Table Entry to be copied.
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
*/
void itlb_pte_copy(pte_t *t, index_t index)
void itlb_pte_copy(pte_t *t, size_t index)
{
tlb_tag_access_reg_t tag;
tlb_data_t data;
200,12 → 199,12
/** ITLB miss handler. */
void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate)
{
uintptr_t va = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
index_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
uintptr_t page_16k = ALIGN_DOWN(istate->tpc, PAGE_SIZE);
size_t index = (istate->tpc >> MMU_PAGE_WIDTH) % MMU_PAGES_PER_PAGE;
pte_t *t;
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
t = page_mapping_find(AS, page_16k);
if (t && PTE_EXECUTABLE(t)) {
/*
* The mapping was found in the software page hash table.
223,7 → 222,8
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
if (as_page_fault(page_16k, PF_ACCESS_EXEC, istate) ==
AS_PF_FAULT) {
do_fast_instruction_access_mmu_miss_fault(istate,
__func__);
}
235,18 → 235,21
* Note that some faults (e.g. kernel faults) were already resolved by the
* low-level, assembly language part of the fast_data_access_mmu_miss handler.
*
* @param tag Content of the TLB Tag Access register as it existed when the
* trap happened. This is to prevent confusion created by clobbered
* Tag Access register during a nested DTLB miss.
* @param istate Interrupted state saved on the stack.
* @param tag Content of the TLB Tag Access register as it existed
* when the trap happened. This is to prevent confusion
* created by clobbered Tag Access register during a nested
* DTLB miss.
* @param istate Interrupted state saved on the stack.
*/
void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate)
{
uintptr_t va;
index_t index;
uintptr_t page_8k;
uintptr_t page_16k;
size_t index;
pte_t *t;
 
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
page_8k = (uint64_t) tag.vpn << MMU_PAGE_WIDTH;
page_16k = ALIGN_DOWN(page_8k, PAGE_SIZE);
index = tag.vpn % MMU_PAGES_PER_PAGE;
 
if (tag.context == ASID_KERNEL) {
254,6 → 257,15
/* NULL access in kernel */
do_fast_data_access_mmu_miss_fault(istate, tag,
__func__);
} else if (page_8k >= end_of_identity) {
/*
* The kernel is accessing the I/O space.
* We still do identity mapping for I/O,
* but without caching.
*/
dtlb_insert_mapping(page_8k, KA2PA(page_8k),
PAGESIZE_8K, false, false);
return;
}
do_fast_data_access_mmu_miss_fault(istate, tag, "Unexpected "
"kernel page fault.");
260,7 → 272,7
}
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
t = page_mapping_find(AS, page_16k);
if (t) {
/*
* The mapping was found in the software page hash table.
278,7 → 290,8
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
if (as_page_fault(page_16k, PF_ACCESS_READ, istate) ==
AS_PF_FAULT) {
do_fast_data_access_mmu_miss_fault(istate, tag,
__func__);
}
287,22 → 300,23
 
/** DTLB protection fault handler.
*
* @param tag Content of the TLB Tag Access register as it existed when the
* trap happened. This is to prevent confusion created by clobbered
* Tag Access register during a nested DTLB miss.
* @param istate Interrupted state saved on the stack.
* @param tag Content of the TLB Tag Access register as it existed
* when the trap happened. This is to prevent confusion
* created by clobbered Tag Access register during a nested
* DTLB miss.
* @param istate Interrupted state saved on the stack.
*/
void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate)
{
uintptr_t va;
index_t index;
uintptr_t page_16k;
size_t index;
pte_t *t;
 
va = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
page_16k = ALIGN_DOWN((uint64_t) tag.vpn << MMU_PAGE_WIDTH, PAGE_SIZE);
index = tag.vpn % MMU_PAGES_PER_PAGE; /* 16K-page emulation */
 
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
t = page_mapping_find(AS, page_16k);
if (t && PTE_WRITABLE(t)) {
/*
* The mapping was found in the software page hash table and is
312,7 → 326,7
t->a = true;
t->d = true;
dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_SECONDARY,
va + index * MMU_PAGE_SIZE);
page_16k + index * MMU_PAGE_SIZE);
dtlb_pte_copy(t, index, false);
#ifdef CONFIG_TSB
dtsb_pte_copy(t, index, false);
324,7 → 338,8
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
if (as_page_fault(page_16k, PF_ACCESS_WRITE, istate) ==
AS_PF_FAULT) {
do_fast_data_access_protection_fault(istate, tag,
__func__);
}
331,6 → 346,26
}
}
 
/** Print TLB entry (for debugging purposes).
*
* The diag field has been left out in order to make this function more generic
* (there is no diag field in US3 architeture).
*
* @param i TLB entry number
* @param t TLB entry tag
* @param d TLB entry data
*/
static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d)
{
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
"ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, "
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
t.context, d.v, d.size, d.nfo, d.ie, d.soft2,
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
}
 
#if defined (US)
 
/** Print contents of both TLBs. */
void tlb_print(void)
{
342,12 → 377,7
for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
d.value = itlb_data_access_read(i);
t.value = itlb_tag_read_read(i);
 
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
"ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
print_tlb_entry(i, t, d);
}
 
printf("D-TLB contents:\n");
354,22 → 384,63
for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
d.value = dtlb_data_access_read(i);
t.value = dtlb_tag_read_read(i);
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, "
"ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, "
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn,
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag,
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g);
print_tlb_entry(i, t, d);
}
}
 
#elif defined (US3)
 
/** Print contents of all TLBs. */
void tlb_print(void)
{
int i;
tlb_data_t d;
tlb_tag_read_reg_t t;
printf("TLB_ISMALL contents:\n");
for (i = 0; i < tlb_ismall_size(); i++) {
d.value = dtlb_data_access_read(TLB_ISMALL, i);
t.value = dtlb_tag_read_read(TLB_ISMALL, i);
print_tlb_entry(i, t, d);
}
printf("TLB_IBIG contents:\n");
for (i = 0; i < tlb_ibig_size(); i++) {
d.value = dtlb_data_access_read(TLB_IBIG, i);
t.value = dtlb_tag_read_read(TLB_IBIG, i);
print_tlb_entry(i, t, d);
}
printf("TLB_DSMALL contents:\n");
for (i = 0; i < tlb_dsmall_size(); i++) {
d.value = dtlb_data_access_read(TLB_DSMALL, i);
t.value = dtlb_tag_read_read(TLB_DSMALL, i);
print_tlb_entry(i, t, d);
}
printf("TLB_DBIG_1 contents:\n");
for (i = 0; i < tlb_dbig_size(); i++) {
d.value = dtlb_data_access_read(TLB_DBIG_0, i);
t.value = dtlb_tag_read_read(TLB_DBIG_0, i);
print_tlb_entry(i, t, d);
}
printf("TLB_DBIG_2 contents:\n");
for (i = 0; i < tlb_dbig_size(); i++) {
d.value = dtlb_data_access_read(TLB_DBIG_1, i);
t.value = dtlb_tag_read_read(TLB_DBIG_1, i);
print_tlb_entry(i, t, d);
}
}
 
#endif
 
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate,
const char *str)
{
fault_if_from_uspace(istate, "%s\n", str);
fault_if_from_uspace(istate, "%s.", str);
dump_istate(istate);
panic("%s\n", str);
panic("%s.", str);
}
 
void do_fast_data_access_mmu_miss_fault(istate_t *istate,
379,12 → 450,12
 
va = tag.vpn << MMU_PAGE_WIDTH;
if (tag.context) {
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
tag.context);
}
dump_istate(istate);
printf("Faulting page: %p, ASID=%d\n", va, tag.context);
panic("%s\n", str);
printf("Faulting page: %p, ASID=%d.\n", va, tag.context);
panic("%s.", str);
}
 
void do_fast_data_access_protection_fault(istate_t *istate,
395,12 → 466,12
va = tag.vpn << MMU_PAGE_WIDTH;
 
if (tag.context) {
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va,
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va,
tag.context);
}
printf("Faulting page: %p, ASID=%d\n", va, tag.context);
dump_istate(istate);
panic("%s\n", str);
panic("%s.", str);
}
 
void dump_sfsr_and_sfar(void)
411,30 → 482,39
sfsr.value = dtlb_sfsr_read();
sfar = dtlb_sfar_read();
#if defined (US)
printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, "
"fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w,
sfsr.ow, sfsr.fv);
#elif defined (US3)
printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, "
"w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft,
sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv);
#endif
printf("DTLB SFAR: address=%p\n", sfar);
dtlb_sfsr_write(0);
}
 
#if defined (US)
/** Invalidate all unlocked ITLB and DTLB entries. */
void tlb_invalidate_all(void)
{
int i;
tlb_data_t d;
tlb_tag_read_reg_t t;
 
/*
* Walk all ITLB and DTLB entries and remove all unlocked mappings.
*
* The kernel doesn't use global mappings so any locked global mappings
* found must have been created by someone else. Their only purpose now
* found must have been created by someone else. Their only purpose now
* is to collide with proper mappings. Invalidate immediately. It should
* be safe to invalidate them as late as now.
*/
 
tlb_data_t d;
tlb_tag_read_reg_t t;
 
for (i = 0; i < ITLB_ENTRY_COUNT; i++) {
d.value = itlb_data_access_read(i);
if (!d.l || d.g) {
444,7 → 524,7
itlb_data_access_write(i, d.value);
}
}
 
for (i = 0; i < DTLB_ENTRY_COUNT; i++) {
d.value = dtlb_data_access_read(i);
if (!d.l || d.g) {
454,9 → 534,20
dtlb_data_access_write(i, d.value);
}
}
 
}
 
#elif defined (US3)
 
/** Invalidate all unlocked ITLB and DTLB entries. */
void tlb_invalidate_all(void)
{
itlb_demap(TLB_DEMAP_ALL, 0, 0);
dtlb_demap(TLB_DEMAP_ALL, 0, 0);
}
 
#endif
 
/** Invalidate all ITLB and DTLB entries that belong to specified ASID
* (Context).
*
484,11 → 575,11
/** Invalidate all ITLB and DTLB entries for specified page range in specified
* address space.
*
* @param asid Address Space ID.
* @param page First page which to sweep out from ITLB and DTLB.
* @param cnt Number of ITLB and DTLB entries to invalidate.
* @param asid Address Space ID.
* @param page First page which to sweep out from ITLB and DTLB.
* @param cnt Number of ITLB and DTLB entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
{
unsigned int i;
tlb_context_reg_t pc_save, ctx;
/branches/arm/kernel/arch/sparc64/src/mm/as.c
89,7 → 89,7
* The count must be calculated with respect to the emualted 16K page
* size.
*/
count_t cnt = ((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
size_t cnt = ((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) *
sizeof(tsb_entry_t)) >> FRAME_WIDTH;
frame_free(KA2PA((uintptr_t) as->arch.itsb));
return cnt;
101,7 → 101,7
int as_create_arch(as_t *as, int flags)
{
#ifdef CONFIG_TSB
tsb_invalidate(as, 0, (count_t) -1);
tsb_invalidate(as, 0, (size_t) -1);
#endif
return 0;
}
164,7 → 164,25
itsb_base_write(tsb_base.value);
tsb_base.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH;
dtsb_base_write(tsb_base.value);
#if defined (US3)
/*
* Clear the extension registers.
* In HelenOS, primary and secondary context registers contain
* equal values and kernel misses (context 0, ie. the nucleus context)
* are excluded from the TSB miss handler, so it makes no sense
* to have separate TSBs for primary, secondary and nucleus contexts.
* Clearing the extension registers will ensure that the value of the
* TSB Base register will be used as an address of TSB, making the code
* compatible with the US port.
*/
itsb_primary_extension_write(0);
itsb_nucleus_extension_write(0);
dtsb_primary_extension_write(0);
dtsb_secondary_extension_write(0);
dtsb_nucleus_extension_write(0);
#endif
#endif
}
 
/** Perform sparc64-specific tasks when an address space is removed from the
/branches/arm/kernel/arch/sparc64/src/mm/tsb.c
50,13 → 50,14
*
* @param as Address space.
* @param page First page to invalidate in TSB.
* @param pages Number of pages to invalidate. Value of (count_t) -1 means the
* @param pages Number of pages to invalidate. Value of (size_t) -1 means the
* whole TSB.
*/
void tsb_invalidate(as_t *as, uintptr_t page, count_t pages)
void tsb_invalidate(as_t *as, uintptr_t page, size_t pages)
{
index_t i0, i;
count_t cnt;
size_t i0;
size_t i;
size_t cnt;
ASSERT(as->arch.itsb && as->arch.dtsb);
63,7 → 64,7
i0 = (page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
ASSERT(i0 < ITSB_ENTRY_COUNT && i0 < DTSB_ENTRY_COUNT);
 
if (pages == (count_t) -1 || (pages * 2) > ITSB_ENTRY_COUNT)
if (pages == (size_t) -1 || (pages * 2) > ITSB_ENTRY_COUNT)
cnt = ITSB_ENTRY_COUNT;
else
cnt = pages * 2;
81,11 → 82,11
* @param t Software PTE.
* @param index Zero if lower 8K-subpage, one if higher 8K subpage.
*/
void itsb_pte_copy(pte_t *t, index_t index)
void itsb_pte_copy(pte_t *t, size_t index)
{
as_t *as;
tsb_entry_t *tsb;
index_t entry;
size_t entry;
 
ASSERT(index <= 1);
112,9 → 113,9
tsb->data.value = 0;
tsb->data.size = PAGESIZE_8K;
tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index;
tsb->data.cp = t->c;
tsb->data.p = t->k; /* p as privileged */
tsb->data.v = t->p;
tsb->data.cp = t->c; /* cp as cache in phys.-idxed, c as cacheable */
tsb->data.p = t->k; /* p as privileged, k as kernel */
tsb->data.v = t->p; /* v as valid, p as present */
write_barrier();
127,11 → 128,11
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage.
* @param ro If true, the mapping is copied read-only.
*/
void dtsb_pte_copy(pte_t *t, index_t index, bool ro)
void dtsb_pte_copy(pte_t *t, size_t index, bool ro)
{
as_t *as;
tsb_entry_t *tsb;
index_t entry;
size_t entry;
ASSERT(index <= 1);
 
173,3 → 174,4
 
/** @}
*/
 
/branches/arm/kernel/arch/sparc64/src/mm/page.c
1,5 → 1,5
/*
* Copyright (c) 2005 Jakub Jermar
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64mm
/** @addtogroup sparc64mm
* @{
*/
/** @file
42,126 → 42,27
#include <align.h>
#include <config.h>
 
#ifdef CONFIG_SMP
/** Entries locked in DTLB of BSP.
*
* Application processors need to have the same locked entries in their DTLBs as
* the bootstrap processor.
*/
static struct {
uintptr_t virt_page;
uintptr_t phys_page;
int pagesize_code;
} bsp_locked_dtlb_entry[DTLB_ENTRY_COUNT];
 
/** Number of entries in bsp_locked_dtlb_entry array. */
static count_t bsp_locked_dtlb_entries = 0;
#endif /* CONFIG_SMP */
 
/** Perform sparc64 specific initialization of paging. */
void page_arch_init(void)
{
if (config.cpu_active == 1) {
if (config.cpu_active == 1)
page_mapping_operations = &ht_mapping_operations;
} else {
 
#ifdef CONFIG_SMP
unsigned int i;
 
/*
* Copy locked DTLB entries from the BSP.
*/
for (i = 0; i < bsp_locked_dtlb_entries; i++) {
dtlb_insert_mapping(bsp_locked_dtlb_entry[i].virt_page,
bsp_locked_dtlb_entry[i].phys_page,
bsp_locked_dtlb_entry[i].pagesize_code, true,
false);
}
#endif
 
}
}
 
/** Map memory-mapped device into virtual memory.
*
* So far, only DTLB is used to map devices into memory. Chances are that there
* will be only a limited amount of devices that the kernel itself needs to
* lock in DTLB.
* We are currently using identity mapping for mapping device registers.
*
* @param physaddr Physical address of the page where the device is located.
* Must be at least page-aligned.
* @param size Size of the device's registers. Must not exceed 4M and must
* include extra space caused by the alignment.
* @param physaddr Physical address of the page where the device is
* located.
* @param size Size of the device's registers.
*
* @return Virtual address of the page where the device is mapped.
*
*/
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
unsigned int order;
unsigned int i;
 
ASSERT(config.cpu_active == 1);
 
struct {
int pagesize_code;
size_t increment;
count_t count;
} sizemap[] = {
{ PAGESIZE_8K, 0, 1 }, /* 8K */
{ PAGESIZE_8K, MMU_PAGE_SIZE, 2 }, /* 16K */
{ PAGESIZE_8K, MMU_PAGE_SIZE, 4 }, /* 32K */
{ PAGESIZE_64K, 0, 1}, /* 64K */
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 2 }, /* 128K */
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 4 }, /* 256K */
{ PAGESIZE_512K, 0, 1 }, /* 512K */
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 2 }, /* 1M */
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 4 }, /* 2M */
{ PAGESIZE_4M, 0, 1 }, /* 4M */
{ PAGESIZE_4M, 512 * MMU_PAGE_SIZE, 2 } /* 8M */
};
ASSERT(ALIGN_UP(physaddr, MMU_PAGE_SIZE) == physaddr);
ASSERT(size <= 8 * 1024 * 1024);
if (size <= MMU_FRAME_SIZE)
order = 0;
else
order = (fnzb64(size - 1) + 1) - MMU_FRAME_WIDTH;
 
/*
* Use virtual addresses that are beyond the limit of physical memory.
* Thus, the physical address space will not be wasted by holes created
* by frame_alloc().
*/
ASSERT(PA2KA(last_frame));
uintptr_t virtaddr = ALIGN_UP(PA2KA(last_frame),
1 << (order + FRAME_WIDTH));
last_frame = ALIGN_UP(KA2PA(virtaddr) + size,
1 << (order + FRAME_WIDTH));
for (i = 0; i < sizemap[order].count; i++) {
/*
* First, insert the mapping into DTLB.
*/
dtlb_insert_mapping(virtaddr + i * sizemap[order].increment,
physaddr + i * sizemap[order].increment,
sizemap[order].pagesize_code, true, false);
#ifdef CONFIG_SMP
/*
* Second, save the information about the mapping for APs.
*/
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].virt_page =
virtaddr + i * sizemap[order].increment;
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].phys_page =
physaddr + i * sizemap[order].increment;
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].pagesize_code =
sizemap[order].pagesize_code;
bsp_locked_dtlb_entries++;
#endif
}
return virtaddr;
return PA2KA(physaddr);
}
 
/** @}
/branches/arm/kernel/arch/sparc64/src/mm/frame.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64mm
/** @addtogroup sparc64mm
* @{
*/
/** @file
79,7 → 79,8
*/
frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
}
 
end_of_identity = PA2KA(last_frame);
}
 
/** @}
/branches/arm/kernel/arch/sparc64/src/mm/cache.S
47,45 → 47,3
retl
! beware SF Erratum #51, do not put the MEMBAR here
nop
 
/** Flush only D-cache lines of one virtual color.
*
* @param o0 Virtual color to be flushed.
*/
.global dcache_flush_color
dcache_flush_color:
mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1
set DCACHE_SIZE / 2, %g2
sllx %g2, %o0, %g2
sub %g2, DCACHE_LINE_SIZE, %g2
0: stxa %g0, [%g2] ASI_DCACHE_TAG
membar #Sync
subcc %g1, 1, %g1
bnz,pt %xcc, 0b
sub %g2, DCACHE_LINE_SIZE, %g2
retl
nop
 
/** Flush only D-cache lines of one virtual color and one tag.
*
* @param o0 Virtual color to lookup the tag.
* @param o1 Tag of the cachelines to be flushed.
*/
.global dcache_flush_tag
dcache_flush_tag:
mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1
set DCACHE_SIZE / 2, %g2
sllx %g2, %o0, %g2
sub %g2, DCACHE_LINE_SIZE, %g2
0: ldxa [%g2] ASI_DCACHE_TAG, %g3
srlx %g3, DCACHE_TAG_SHIFT, %g3
cmp %g3, %o1
bnz 1f
nop
stxa %g0, [%g2] ASI_DCACHE_TAG
membar #Sync
1: subcc %g1, 1, %g1
bnz,pt %xcc, 0b
sub %g2, DCACHE_LINE_SIZE, %g2
retl
nop
/branches/arm/kernel/arch/sparc64/src/drivers/fhc.c
45,6 → 45,7
#include <mm/slab.h>
#include <arch/types.h>
#include <genarch/ofw/ofw_tree.h>
#include <sysinfo/sysinfo.h>
 
fhc_t *central_fhc = NULL;
 
70,7 → 71,7
if (!prop || !prop->value)
return NULL;
count_t regs = prop->size / sizeof(ofw_central_reg_t);
size_t regs = prop->size / sizeof(ofw_central_reg_t);
if (regs + 1 < UART_IMAP_REG)
return NULL;
 
86,6 → 87,13
 
fhc->uart_imap = (uint32_t *) hw_map(paddr, reg->size);
/*
* Set sysinfo data needed by the uspace FHC driver.
*/
sysinfo_set_item_val("fhc.uart.size", NULL, reg->size);
sysinfo_set_item_val("fhc.uart.physical", NULL, paddr);
sysinfo_set_item_val("kbd.cir.fhc", NULL, 1);
 
return fhc;
}
 
96,13 → 104,14
fhc->uart_imap[FHC_UART_IMAP] |= IMAP_V_MASK;
break;
default:
panic("Unexpected INR (%d)\n", inr);
panic("Unexpected INR (%d).", inr);
break;
}
}
 
void fhc_clear_interrupt(fhc_t *fhc, int inr)
void fhc_clear_interrupt(void *fhcp, int inr)
{
fhc_t *fhc = (fhc_t *)fhcp;
ASSERT(fhc->uart_imap);
 
switch (inr) {
110,7 → 119,7
fhc->uart_imap[FHC_UART_ICLR] = 0;
break;
default:
panic("Unexpected INR (%d)\n", inr);
panic("Unexpected INR (%d).", inr);
break;
}
}
/branches/arm/kernel/arch/sparc64/src/drivers/pci.c
42,43 → 42,41
#include <arch/types.h>
#include <debug.h>
#include <print.h>
#include <func.h>
#include <string.h>
#include <arch/asm.h>
#include <sysinfo/sysinfo.h>
 
#define PCI_SABRE_REGS_REG 0
#define SABRE_INTERNAL_REG 0
#define PSYCHO_INTERNAL_REG 2
 
#define PCI_SABRE_IMAP_BASE 0x200
#define PCI_SABRE_ICLR_BASE 0x300
#define OBIO_IMR_BASE 0x200
#define OBIO_IMR(ino) (OBIO_IMR_BASE + ((ino) & INO_MASK))
 
#define PCI_PSYCHO_REGS_REG 2
#define OBIO_CIR_BASE 0x300
#define OBIO_CIR(ino) (OBIO_CIR_BASE + ((ino) & INO_MASK))
 
#define PCI_PSYCHO_IMAP_BASE 0x200
#define PCI_PSYCHO_ICLR_BASE 0x300
static void obio_enable_interrupt(pci_t *, int);
static void obio_clear_interrupt(pci_t *, int);
 
static pci_t *pci_sabre_init(ofw_tree_node_t *node);
static void pci_sabre_enable_interrupt(pci_t *pci, int inr);
static void pci_sabre_clear_interrupt(pci_t *pci, int inr);
static pci_t *pci_sabre_init(ofw_tree_node_t *);
static pci_t *pci_psycho_init(ofw_tree_node_t *);
 
static pci_t *pci_psycho_init(ofw_tree_node_t *node);
static void pci_psycho_enable_interrupt(pci_t *pci, int inr);
static void pci_psycho_clear_interrupt(pci_t *pci, int inr);
 
/** PCI operations for Sabre model. */
static pci_operations_t pci_sabre_ops = {
.enable_interrupt = pci_sabre_enable_interrupt,
.clear_interrupt = pci_sabre_clear_interrupt
.enable_interrupt = obio_enable_interrupt,
.clear_interrupt = obio_clear_interrupt
};
/** PCI operations for Psycho model. */
static pci_operations_t pci_psycho_ops = {
.enable_interrupt = pci_psycho_enable_interrupt,
.clear_interrupt = pci_psycho_clear_interrupt
.enable_interrupt = obio_enable_interrupt,
.clear_interrupt = obio_clear_interrupt
};
 
/** Initialize PCI controller (model Sabre).
*
* @param node OpenFirmware device tree node of the Sabre.
* @param node OpenFirmware device tree node of the Sabre.
*
* @return Address of the initialized PCI structure.
* @return Address of the initialized PCI structure.
*/
pci_t *pci_sabre_init(ofw_tree_node_t *node)
{
93,13 → 91,14
return NULL;
 
ofw_upa_reg_t *reg = prop->value;
count_t regs = prop->size / sizeof(ofw_upa_reg_t);
size_t regs = prop->size / sizeof(ofw_upa_reg_t);
 
if (regs < PCI_SABRE_REGS_REG + 1)
if (regs < SABRE_INTERNAL_REG + 1)
return NULL;
 
uintptr_t paddr;
if (!ofw_upa_apply_ranges(node->parent, &reg[PCI_SABRE_REGS_REG], &paddr))
if (!ofw_upa_apply_ranges(node->parent, &reg[SABRE_INTERNAL_REG],
&paddr))
return NULL;
 
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC);
108,8 → 107,14
 
pci->model = PCI_SABRE;
pci->op = &pci_sabre_ops;
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_SABRE_REGS_REG].size);
pci->reg = (uint64_t *) hw_map(paddr, reg[SABRE_INTERNAL_REG].size);
 
/*
* Set sysinfo data needed by the uspace OBIO driver.
*/
sysinfo_set_item_val("obio.base.physical", NULL, paddr);
sysinfo_set_item_val("kbd.cir.obio", NULL, 1);
 
return pci;
}
 
116,9 → 121,9
 
/** Initialize the Psycho PCI controller.
*
* @param node OpenFirmware device tree node of the Psycho.
* @param node OpenFirmware device tree node of the Psycho.
*
* @return Address of the initialized PCI structure.
* @return Address of the initialized PCI structure.
*/
pci_t *pci_psycho_init(ofw_tree_node_t *node)
{
133,13 → 138,14
return NULL;
 
ofw_upa_reg_t *reg = prop->value;
count_t regs = prop->size / sizeof(ofw_upa_reg_t);
size_t regs = prop->size / sizeof(ofw_upa_reg_t);
 
if (regs < PCI_PSYCHO_REGS_REG + 1)
if (regs < PSYCHO_INTERNAL_REG + 1)
return NULL;
 
uintptr_t paddr;
if (!ofw_upa_apply_ranges(node->parent, &reg[PCI_PSYCHO_REGS_REG], &paddr))
if (!ofw_upa_apply_ranges(node->parent, &reg[PSYCHO_INTERNAL_REG],
&paddr))
return NULL;
 
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC);
148,31 → 154,27
 
pci->model = PCI_PSYCHO;
pci->op = &pci_psycho_ops;
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_PSYCHO_REGS_REG].size);
pci->reg = (uint64_t *) hw_map(paddr, reg[PSYCHO_INTERNAL_REG].size);
 
/*
* Set sysinfo data needed by the uspace OBIO driver.
*/
sysinfo_set_item_val("obio.base.physical", NULL, paddr);
sysinfo_set_item_val("kbd.cir.obio", NULL, 1);
 
return pci;
}
 
void pci_sabre_enable_interrupt(pci_t *pci, int inr)
void obio_enable_interrupt(pci_t *pci, int inr)
{
pci->reg[PCI_SABRE_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK;
pci->reg[OBIO_IMR(inr & INO_MASK)] |= IMAP_V_MASK;
}
 
void pci_sabre_clear_interrupt(pci_t *pci, int inr)
void obio_clear_interrupt(pci_t *pci, int inr)
{
pci->reg[PCI_SABRE_ICLR_BASE + (inr & INO_MASK)] = 0;
pci->reg[OBIO_CIR(inr & INO_MASK)] = 0; /* set IDLE */
}
 
void pci_psycho_enable_interrupt(pci_t *pci, int inr)
{
pci->reg[PCI_PSYCHO_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK;
}
 
void pci_psycho_clear_interrupt(pci_t *pci, int inr)
{
pci->reg[PCI_PSYCHO_ICLR_BASE + (inr & INO_MASK)] = 0;
}
 
/** Initialize PCI controller. */
pci_t *pci_init(ofw_tree_node_t *node)
{
181,7 → 183,7
/*
* First, verify this is a PCI node.
*/
ASSERT(strcmp(ofw_tree_node_name(node), "pci") == 0);
ASSERT(str_cmp(ofw_tree_node_name(node), "pci") == 0);
 
/*
* Determine PCI controller model.
190,13 → 192,13
if (!prop || !prop->value)
return NULL;
if (strcmp(prop->value, "SUNW,sabre") == 0) {
if (str_cmp(prop->value, "SUNW,sabre") == 0) {
/*
* PCI controller Sabre.
* This model is found on UltraSPARC IIi based machines.
*/
return pci_sabre_init(node);
} else if (strcmp(prop->value, "SUNW,psycho") == 0) {
} else if (str_cmp(prop->value, "SUNW,psycho") == 0) {
/*
* PCI controller Psycho.
* Used on UltraSPARC II based processors, for instance,
215,14 → 217,14
 
void pci_enable_interrupt(pci_t *pci, int inr)
{
ASSERT(pci->model);
ASSERT(pci->op && pci->op->enable_interrupt);
pci->op->enable_interrupt(pci, inr);
}
 
void pci_clear_interrupt(pci_t *pci, int inr)
void pci_clear_interrupt(void *pcip, int inr)
{
ASSERT(pci->model);
pci_t *pci = (pci_t *)pcip;
 
ASSERT(pci->op && pci->op->clear_interrupt);
pci->op->clear_interrupt(pci, inr);
}
/branches/arm/kernel/arch/sparc64/src/drivers/sgcn.c
0,0 → 1,387
/*
* Copyright (c) 2008 Pavel Rimsky
* 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 sparc64
* @{
*/
/**
* @file
* @brief SGCN driver.
*/
 
#include <arch.h>
#include <arch/drivers/sgcn.h>
#include <arch/drivers/kbd.h>
#include <genarch/ofw/ofw_tree.h>
#include <debug.h>
#include <string.h>
#include <print.h>
#include <mm/page.h>
#include <proc/thread.h>
#include <console/chardev.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <synch/spinlock.h>
 
#define POLL_INTERVAL 10000
 
/*
* Physical address at which the SBBC starts. This value has been obtained
* by inspecting (using Simics) memory accesses made by OBP. It is valid
* for the Simics-simulated Serengeti machine. The author of this code is
* not sure whether this value is valid generally.
*/
#define SBBC_START 0x63000000000
 
/* offset of SRAM within the SBBC memory */
#define SBBC_SRAM_OFFSET 0x900000
 
/* size (in bytes) of the physical memory area which will be mapped */
#define MAPPED_AREA_SIZE (128 * 1024)
 
/* magic string contained at the beginning of SRAM */
#define SRAM_TOC_MAGIC "TOCSRAM"
 
/*
* Key into the SRAM table of contents which identifies the entry
* describing the OBP console buffer. It is worth mentioning
* that the OBP console buffer is not the only console buffer
* which can be used. It is, however, used because when the kernel
* is running, the OBP buffer is not used by OBP any more but OBP
* has already made necessary arrangements so that the output will
* be read from the OBP buffer and input will go to the OBP buffer.
* Therefore HelenOS needs to make no such arrangements any more.
*/
#define CONSOLE_KEY "OBPCONS"
 
/* magic string contained at the beginning of the console buffer */
#define SGCN_BUFFER_MAGIC "CON"
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the SRAM beginning.
*/
#define SRAM(type, offset) ((type *) (sram_begin + (offset)))
 
/* Returns a pointer to the SRAM table of contents. */
#define SRAM_TOC (SRAM(iosram_toc_t, 0))
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the console buffer beginning.
*/
#define SGCN_BUFFER(type, offset) \
((type *) (sgcn_buffer_begin + (offset)))
 
/** Returns a pointer to the console buffer header. */
#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0))
 
/** starting address of SRAM, will be set by the init_sram_begin function */
static uintptr_t sram_begin;
 
/**
* starting address of the SGCN buffer, will be set by the
* init_sgcn_buffer_begin function
*/
static uintptr_t sgcn_buffer_begin;
 
/* true iff the kernel driver should ignore pressed keys */
static bool kbd_disabled;
 
/*
* Ensures that writing to the buffer and consequent update of the write pointer
* are together one atomic operation.
*/
SPINLOCK_INITIALIZE(sgcn_output_lock);
 
/*
* Prevents the input buffer read/write pointers from getting to inconsistent
* state.
*/
SPINLOCK_INITIALIZE(sgcn_input_lock);
 
 
/* functions referenced from definitions of I/O operations structures */
static void sgcn_putchar(outdev_t *, const wchar_t, bool);
 
/** SGCN output device operations */
static outdev_operations_t sgcnout_ops = {
.write = sgcn_putchar
};
 
static outdev_t sgcnout; /**< SGCN output device. */
 
/**
* Set some sysinfo values (SRAM address and SRAM size).
*/
static void register_sram(uintptr_t sram_begin_physical)
{
sysinfo_set_item_val("sram.area.size", NULL, MAPPED_AREA_SIZE);
sysinfo_set_item_val("sram.address.physical", NULL,
sram_begin_physical);
}
 
/**
* Initializes the starting address of SRAM.
*
* The SRAM starts 0x900000 + C bytes behind the SBBC start in the
* physical memory, where C is the value read from the "iosram-toc"
* property of the "/chosen" OBP node. The sram_begin variable will
* be set to the virtual address which maps to the SRAM physical
* address.
*/
static void init_sram_begin(void)
{
ofw_tree_node_t *chosen;
ofw_tree_property_t *iosram_toc;
uintptr_t sram_begin_physical;
 
chosen = ofw_tree_lookup("/chosen");
if (!chosen)
panic("Cannot find '/chosen'.");
 
iosram_toc = ofw_tree_getprop(chosen, "iosram-toc");
if (!iosram_toc)
panic("Cannot find property 'iosram-toc'.");
if (!iosram_toc->value)
panic("Cannot find SRAM TOC.");
 
sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET
+ *((uint32_t *) iosram_toc->value);
sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE);
register_sram(sram_begin_physical);
}
 
/**
* Initializes the starting address of the SGCN buffer.
*
* The offset of the SGCN buffer within SRAM is obtained from the
* SRAM table of contents. The table of contents contains
* information about several buffers, among which there is an OBP
* console buffer - this one will be used as the SGCN buffer.
*
* This function also writes the offset of the SGCN buffer within SRAM
* under the sram.buffer.offset sysinfo key.
*/
static void sgcn_buffer_begin_init(void)
{
static bool initialized;
if (initialized)
return;
 
init_sram_begin();
ASSERT(str_cmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0);
/* lookup TOC entry with the correct key */
uint32_t i;
for (i = 0; i < MAX_TOC_ENTRIES; i++) {
if (str_cmp(SRAM_TOC->keys[i].key, CONSOLE_KEY) == 0)
break;
}
ASSERT(i < MAX_TOC_ENTRIES);
sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset;
sysinfo_set_item_val("sram.buffer.offset", NULL,
SRAM_TOC->keys[i].offset);
initialized = true;
}
 
/**
* Writes a single character to the SGCN (circular) output buffer
* and updates the output write pointer so that SGCN gets to know
* that the character has been written.
*/
static void sgcn_do_putchar(const char c)
{
uint32_t begin = SGCN_BUFFER_HEADER->out_begin;
uint32_t end = SGCN_BUFFER_HEADER->out_end;
uint32_t size = end - begin;
/* we need pointers to volatile variables */
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
 
/*
* Write the character and increment the write pointer modulo the
* output buffer size. Note that if we are to rewrite a character
* which has not been read by the SGCN controller yet (i.e. the output
* buffer is full), we need to wait until the controller reads some more
* characters. We wait actively, which means that all threads waiting
* for the lock are blocked. However, this situation is
* 1) rare - the output buffer is big, so filling the whole
* output buffer is improbable
* 2) short-lasting - it will take the controller only a fraction
* of millisecond to pick the unread characters up
* 3) not serious - the blocked threads are those that print something
* to user console, which is not a time-critical operation
*/
uint32_t new_wrptr = (((*out_wrptr_ptr) - begin + 1) % size) + begin;
while (*out_rdptr_ptr == new_wrptr)
;
*buf_ptr = c;
*out_wrptr_ptr = new_wrptr;
}
 
/**
* SGCN output operation. Prints a single character to the SGCN. Newline
* character is converted to CRLF.
*/
static void sgcn_putchar(outdev_t *od, const wchar_t ch, bool silent)
{
if (!silent) {
spinlock_lock(&sgcn_output_lock);
if (ascii_check(ch)) {
if (ch == '\n')
sgcn_do_putchar('\r');
sgcn_do_putchar(ch);
} else
sgcn_do_putchar(U_SPECIAL);
spinlock_unlock(&sgcn_output_lock);
}
}
 
/**
* Grabs the input for kernel.
*/
void sgcn_grab(void)
{
kbd_disabled = false;
}
 
/**
* Releases the input so that userspace can use it.
*/
void sgcn_release(void)
{
kbd_disabled = true;
}
 
/**
* Function regularly called by the keyboard polling thread. Finds out whether
* there are some unread characters in the input queue. If so, it picks them up
* and sends them to the upper layers of HelenOS.
*/
static void sgcn_poll(sgcn_instance_t *instance)
{
uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
uint32_t end = SGCN_BUFFER_HEADER->in_end;
uint32_t size = end - begin;
 
if (kbd_disabled)
return;
 
spinlock_lock(&sgcn_input_lock);
/* we need pointers to volatile variables */
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
while (*in_rdptr_ptr != *in_wrptr_ptr) {
buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
char c = *buf_ptr;
*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
indev_push_character(instance->srlnin, c);
}
 
spinlock_unlock(&sgcn_input_lock);
}
 
/**
* Polling thread function.
*/
static void ksgcnpoll(void *instance) {
while (1) {
if (!silent)
sgcn_poll(instance);
thread_usleep(POLL_INTERVAL);
}
}
 
/**
* A public function which initializes input from the Serengeti console.
*/
sgcn_instance_t *sgcnin_init(void)
{
sgcn_buffer_begin_init();
sgcn_instance_t *instance =
malloc(sizeof(sgcn_instance_t), FRAME_ATOMIC);
if (instance) {
instance->srlnin = NULL;
instance->thread = thread_create(ksgcnpoll, instance, TASK, 0,
"ksgcnpoll", true);
if (!instance->thread) {
free(instance);
return NULL;
}
}
return instance;
}
 
void sgcnin_wire(sgcn_instance_t *instance, indev_t *srlnin)
{
ASSERT(instance);
ASSERT(srlnin);
 
instance->srlnin = srlnin;
thread_ready(instance->thread);
 
sysinfo_set_item_val("kbd", NULL, true);
}
 
/**
* A public function which initializes output to the Serengeti console.
*/
void sgcnout_init(void)
{
sgcn_buffer_begin_init();
 
sysinfo_set_item_val("fb.kind", NULL, 4);
 
outdev_initialize("sgcnout", &sgcnout, &sgcnout_ops);
stdout = &sgcnout;
}
 
/** @}
*/
/branches/arm/kernel/arch/sparc64/src/drivers/kbd.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
34,99 → 34,160
 
#include <arch/drivers/kbd.h>
#include <genarch/ofw/ofw_tree.h>
 
#ifdef CONFIG_SUN_KBD
#include <genarch/kbrd/kbrd.h>
#endif
#ifdef CONFIG_Z8530
#include <genarch/kbd/z8530.h>
#include <genarch/drivers/z8530/z8530.h>
#endif
#ifdef CONFIG_NS16550
#include <genarch/kbd/ns16550.h>
#include <genarch/drivers/ns16550/ns16550.h>
#endif
#include <ddi/device.h>
 
#include <console/console.h>
#include <ddi/irq.h>
#include <arch/mm/page.h>
#include <arch/types.h>
#include <align.h>
#include <func.h>
#include <string.h>
#include <print.h>
#include <sysinfo/sysinfo.h>
 
kbd_type_t kbd_type = KBD_UNKNOWN;
#ifdef CONFIG_SUN_KBD
 
/** Initialize keyboard.
*
* Traverse OpenFirmware device tree in order to find necessary
* info about the keyboard device.
*
* @param node Keyboard device node.
*/
void kbd_init(ofw_tree_node_t *node)
#ifdef CONFIG_Z8530
 
static bool kbd_z8530_init(ofw_tree_node_t *node)
{
size_t offset;
uintptr_t aligned_addr;
ofw_tree_property_t *prop;
const char *name;
const char *name = ofw_tree_node_name(node);
name = ofw_tree_node_name(node);
if (str_cmp(name, "zs") != 0)
return false;
/*
* Determine keyboard serial controller type.
* Read 'interrupts' property.
*/
if (strcmp(name, "zs") == 0)
kbd_type = KBD_Z8530;
else if (strcmp(name, "su") == 0)
kbd_type = KBD_NS16550;
ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts");
if ((!prop) || (!prop->value)) {
printf("z8530: Unable to find interrupts property\n");
return false;
}
if (kbd_type == KBD_UNKNOWN) {
printf("Unknown keyboard device.\n");
return;
uint32_t interrupts = *((uint32_t *) prop->value);
/*
* Read 'reg' property.
*/
prop = ofw_tree_getprop(node, "reg");
if ((!prop) || (!prop->value)) {
printf("z8530: Unable to find reg property\n");
return false;
}
size_t size = ((ofw_fhc_reg_t *) prop->value)->size;
uintptr_t pa;
if (!ofw_fhc_apply_ranges(node->parent,
((ofw_fhc_reg_t *) prop->value), &pa)) {
printf("z8530: Failed to determine address\n");
return false;
}
inr_t inr;
cir_t cir;
void *cir_arg;
if (!ofw_fhc_map_interrupt(node->parent,
((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir,
&cir_arg)) {
printf("z8530: Failed to determine interrupt\n");
return false;
}
/*
* Read 'interrupts' property.
* We need to pass aligned address to hw_map().
* However, the physical keyboard address can
* be pretty much unaligned, depending on the
* underlying controller.
*/
uint32_t interrupts;
prop = ofw_tree_getprop(node, "interrupts");
if (!prop || !prop->value)
panic("Can't find \"interrupts\" property.\n");
interrupts = *((uint32_t *) prop->value);
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
size_t offset = pa - aligned_addr;
z8530_t *z8530 = (z8530_t *)
(hw_map(aligned_addr, offset + size) + offset);
z8530_instance_t *z8530_instance = z8530_init(z8530, inr, cir, cir_arg);
if (z8530_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
z8530_wire(z8530_instance, kbrd);
}
}
/*
* This is the necessary evil until the userspace drivers are
* entirely self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, inr);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) z8530);
sysinfo_set_item_val("kbd.address.physical", NULL, pa);
sysinfo_set_item_val("kbd.type.z8530", NULL, true);
return true;
}
 
#endif /* CONFIG_Z8530 */
 
#ifdef CONFIG_NS16550
 
static bool kbd_ns16550_init(ofw_tree_node_t *node)
{
const char *name = ofw_tree_node_name(node);
if (str_cmp(name, "su") != 0)
return false;
/*
* Read 'interrupts' property.
*/
ofw_tree_property_t *prop = ofw_tree_getprop(node, "interrupts");
if ((!prop) || (!prop->value)) {
printf("ns16550: Unable to find interrupts property\n");
return false;
}
uint32_t interrupts = *((uint32_t *) prop->value);
/*
* Read 'reg' property.
*/
prop = ofw_tree_getprop(node, "reg");
if (!prop || !prop->value)
panic("Can't find \"reg\" property.\n");
if ((!prop) || (!prop->value)) {
printf("ns16550: Unable to find reg property\n");
return false;
}
size_t size = ((ofw_ebus_reg_t *) prop->value)->size;
uintptr_t pa;
size_t size;
if (!ofw_ebus_apply_ranges(node->parent,
((ofw_ebus_reg_t *) prop->value), &pa)) {
printf("ns16550: Failed to determine address\n");
return false;
}
inr_t inr;
devno_t devno = device_assign_devno();
switch (kbd_type) {
case KBD_Z8530:
size = ((ofw_fhc_reg_t *) prop->value)->size;
if (!ofw_fhc_apply_ranges(node->parent, ((ofw_fhc_reg_t *) prop->value) , &pa)) {
printf("Failed to determine keyboard address.\n");
return;
}
if (!ofw_fhc_map_interrupt(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) {
printf("Failed to determine keyboard interrupt.\n");
return;
}
break;
case KBD_NS16550:
size = ((ofw_ebus_reg_t *) prop->value)->size;
if (!ofw_ebus_apply_ranges(node->parent, ((ofw_ebus_reg_t *) prop->value) , &pa)) {
printf("Failed to determine keyboard address.\n");
return;
}
if (!ofw_ebus_map_interrupt(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) {
printf("Failed to determine keyboard interrupt.\n");
return;
};
break;
 
default:
panic("Unexpected type.\n");
cir_t cir;
void *cir_arg;
if (!ofw_ebus_map_interrupt(node->parent,
((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir,
&cir_arg)) {
printf("ns16550: Failed to determine interrupt\n");
return false;
}
/*
135,25 → 196,58
* be pretty much unaligned, depending on the
* underlying controller.
*/
aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
offset = pa - aligned_addr;
uintptr_t vaddr = hw_map(aligned_addr, offset + size) + offset;
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
size_t offset = pa - aligned_addr;
ns16550_t *ns16550 = (ns16550_t *)
(hw_map(aligned_addr, offset + size) + offset);
ns16550_instance_t *ns16550_instance = ns16550_init(ns16550, inr, cir, cir_arg);
if (ns16550_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
ns16550_wire(ns16550_instance, kbrd);
}
}
/*
* This is the necessary evil until the userspace drivers are
* entirely self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, inr);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) ns16550);
sysinfo_set_item_val("kbd.address.physical", NULL, pa);
sysinfo_set_item_val("kbd.type.ns16550", NULL, true);
return true;
}
 
switch (kbd_type) {
#endif /* CONFIG_NS16550 */
 
/** Initialize keyboard.
*
* Traverse OpenFirmware device tree in order to find necessary
* info about the keyboard device.
*
* @param node Keyboard device node.
*
*/
void kbd_init(ofw_tree_node_t *node)
{
#ifdef CONFIG_Z8530
case KBD_Z8530:
z8530_init(devno, inr, vaddr);
break;
kbd_z8530_init(node);
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
ns16550_init(devno, inr, vaddr);
break;
kbd_ns16550_init(node);
#endif
default:
printf("Kernel is not compiled with the necessary keyboard driver this machine requires.\n");
}
}
 
#endif /* CONFIG_SUN_KBD */
 
/** @}
*/
/branches/arm/kernel/arch/sparc64/src/drivers/scr.c
37,7 → 37,7
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <arch/types.h>
#include <func.h>
#include <string.h>
#include <align.h>
#include <print.h>
 
55,23 → 55,30
void scr_init(ofw_tree_node_t *node)
{
ofw_tree_property_t *prop;
ofw_pci_reg_t *pci_reg;
ofw_pci_reg_t pci_abs_reg;
ofw_upa_reg_t *upa_reg;
ofw_sbus_reg_t *sbus_reg;
const char *name;
name = ofw_tree_node_name(node);
if (strcmp(name, "SUNW,m64B") == 0)
if (str_cmp(name, "SUNW,m64B") == 0)
scr_type = SCR_ATYFB;
else if (strcmp(name, "SUNW,ffb") == 0)
else if (str_cmp(name, "SUNW,XVR-100") == 0)
scr_type = SCR_XVR;
else if (str_cmp(name, "SUNW,ffb") == 0)
scr_type = SCR_FFB;
else if (strcmp(name, "cgsix") == 0)
else if (str_cmp(name, "cgsix") == 0)
scr_type = SCR_CGSIX;
if (scr_type == SCR_UNKNOWN) {
printf("Unknown keyboard device.\n");
printf("Unknown screen device.\n");
return;
}
uintptr_t fb_addr;
unsigned int fb_offset = 0;
uint32_t fb_width = 0;
uint32_t fb_height = 0;
uint32_t fb_depth = 0;
97,7 → 104,7
 
prop = ofw_tree_getprop(node, "reg");
if (!prop)
panic("Can't find \"reg\" property.\n");
panic("Cannot find 'reg' property.");
 
switch (scr_type) {
case SCR_ATYFB:
106,15 → 113,15
return;
}
ofw_pci_reg_t *fb_reg = &((ofw_pci_reg_t *) prop->value)[1];
ofw_pci_reg_t abs_reg;
pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
if (!ofw_pci_reg_absolutize(node, fb_reg, &abs_reg)) {
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
printf("Failed to absolutize fb register.\n");
return;
}
if (!ofw_pci_apply_ranges(node->parent, &abs_reg , &fb_addr)) {
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
&fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
142,12 → 149,56
}
break;
case SCR_XVR:
if (prop->size / sizeof(ofw_pci_reg_t) < 2) {
printf("Too few screen registers.\n");
return;
}
pci_reg = &((ofw_pci_reg_t *) prop->value)[1];
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) {
printf("Failed to absolutize fb register.\n");
return;
}
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg,
&fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
 
fb_offset = 4 * 0x2000;
 
switch (fb_depth) {
case 8:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_INDIRECT_8;
break;
case 16:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_5_6_5;
break;
case 24:
fb_scanline = fb_linebytes * 4;
visual = VISUAL_RGB_8_8_8_0;
break;
case 32:
fb_scanline = fb_linebytes * (fb_depth >> 3);
visual = VISUAL_RGB_0_8_8_8;
break;
default:
printf("Unsupported bits per pixel.\n");
return;
}
break;
case SCR_FFB:
fb_scanline = 8192;
visual = VISUAL_BGR_0_8_8_8;
 
ofw_upa_reg_t *reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP];
if (!ofw_upa_apply_ranges(node->parent, reg, &fb_addr)) {
upa_reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP];
if (!ofw_upa_apply_ranges(node->parent, upa_reg, &fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
164,8 → 215,8
return;
}
ofw_sbus_reg_t *cg6_reg = &((ofw_sbus_reg_t *) prop->value)[0];
if (!ofw_sbus_apply_ranges(node->parent, cg6_reg, &fb_addr)) {
sbus_reg = &((ofw_sbus_reg_t *) prop->value)[0];
if (!ofw_sbus_apply_ranges(node->parent, sbus_reg, &fb_addr)) {
printf("Failed to determine screen address.\n");
return;
}
172,11 → 223,24
break;
default:
panic("Unexpected type.\n");
panic("Unexpected type.");
}
 
fb_init(fb_addr, fb_width, fb_height, fb_scanline, visual);
fb_properties_t props = {
.addr = fb_addr,
.offset = fb_offset,
.x = fb_width,
.y = fb_height,
.scan = fb_scanline,
.visual = visual,
};
fb_init(&props);
}
 
void scr_redraw(void)
{
fb_redraw();
}
 
/** @}
*/
/branches/arm/kernel/arch/sparc64/src/drivers/tick.c
45,11 → 45,12
 
#define TICK_RESTART_TIME 50 /* Worst case estimate. */
 
/** Initialize tick interrupt. */
/** Initialize tick and stick interrupt. */
void tick_init(void)
{
/* initialize TICK interrupt */
tick_compare_reg_t compare;
 
interrupt_register(14, "tick_int", tick_interrupt);
compare.int_dis = false;
compare.tick_cmpr = CPU->arch.clock_frequency / HZ;
56,6 → 57,21
CPU->arch.next_tick_cmpr = compare.tick_cmpr;
tick_compare_write(compare.value);
tick_write(0);
 
#if defined (US3)
/* disable STICK interrupts and clear any pending ones */
tick_compare_reg_t stick_compare;
softint_reg_t clear;
 
stick_compare.value = stick_compare_read();
stick_compare.int_dis = true;
stick_compare.tick_cmpr = 0;
stick_compare_write(stick_compare.value);
 
clear.value = 0;
clear.stick_int = 1;
clear_softint_write(clear.value);
#endif
}
 
/** Process tick interrupt.
67,7 → 83,7
{
softint_reg_t softint, clear;
uint64_t drift;
 
softint.value = softint_read();
/*
/branches/arm/kernel/arch/sparc64/src/dummy.s
42,5 → 42,5
 
.global cpu_halt
cpu_halt:
b cpu_halt
ba %xcc, cpu_halt
nop
/branches/arm/kernel/arch/sparc64/src/trap/trap_table.S
341,7 → 341,7
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE
.global trap_instruction_\cur\()_tl0
trap_instruction_\cur\()_tl0:
ba trap_instruction_handler
ba %xcc, trap_instruction_handler
mov \cur, %g2
.endr
 
478,9 → 478,9
*/
rdpr %tl, %g3
cmp %g3, 1
be 1f
be %xcc, 1f
nop
0: ba 0b ! this is for debugging, if we ever get here
0: ba %xcc, 0b ! this is for debugging, if we ever get here
nop ! it will be easy to find
 
1:
499,7 → 499,7
wrpr %g4, 0, %cwp ! resynchronize CWP
 
andcc %g3, TSTATE_PRIV_BIT, %g0 ! if this trap came from the privileged mode...
bnz 0f ! ...skip setting of kernel stack and primary context
bnz %xcc, 0f ! ...skip setting of kernel stack and primary context
nop
.endif
545,7 → 545,7
flush %l0
 
.if NOT(\is_syscall)
ba 1f
ba %xcc, 1f
nop
0:
save %sp, -PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE, %sp
606,10 → 606,10
add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1
.else
/*
* Call the higher-level syscall handler.
* Call the higher-level syscall handler and enable interrupts.
*/
call syscall_handler
nop
wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT | PSTATE_IE_BIT, %pstate
mov %o0, %i0 ! copy the value returned by the syscall
.endif
 
672,7 → 672,7
and %l0, NWINDOWS - 1, %l0 ! %l0 mod NWINDOWS
rdpr %cwp, %l1
cmp %l0, %l1
bz 0f ! CWP is ok
bz %xcc, 0f ! CWP is ok
nop
 
/*
712,7 → 712,7
.if NOT(\is_syscall)
rdpr %tstate, %g1
andcc %g1, TSTATE_PRIV_BIT, %g0 ! if we are not returning to userspace...,
bnz 1f ! ...skip restoring userspace windows
bnz %xcc, 1f ! ...skip restoring userspace windows
nop
.endif
 
748,9 → 748,8
* Fill all windows stored in the buffer.
*/
clr %g4
set PAGE_SIZE - 1, %g5
0: andcc %g7, %g5, %g0 ! PAGE_SIZE alignment check
bz 0f ! %g7 is page-aligned, no more windows to refill
0: andcc %g7, UWB_ALIGNMENT - 1, %g0 ! alignment check
bz %xcc, 0f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill
nop
 
add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7
775,7 → 774,7
and %g3, NWINDOWS - 1, %g3
wrpr %g3, 0, %cwp ! switch to the preceeding window
 
ba 0b
ba %xcc, 0b
inc %g4
 
0:
786,7 → 785,7
wrpr %g1, 0, %cwp
add %g4, %g2, %g2
cmp %g2, NWINDOWS - 2
bg 2f ! fix the CANRESTORE=NWINDOWS-1 anomaly
bg %xcc, 2f ! fix the CANRESTORE=NWINDOWS-1 anomaly
mov NWINDOWS - 2, %g1 ! use dealy slot for both cases
sub %g1, %g2, %g1
/branches/arm/kernel/arch/sparc64/src/trap/exception.c
40,62 → 40,67
#include <arch/asm.h>
#include <arch/register.h>
#include <debug.h>
#include <print.h>
#include <symtab.h>
#include <print.h>
 
void dump_istate(istate_t *istate)
{
char *tpcs, *tnpcs;
 
tpcs = symtab_fmt_name_lookup(istate->tpc);
tnpcs = symtab_fmt_name_lookup(istate->tnpc);
 
printf("TSTATE=%#" PRIx64 "\n", istate->tstate);
printf("TPC=%#" PRIx64 " (%s)\n", istate->tpc, get_symtab_entry(istate->tpc));
printf("TNPC=%#" PRIx64 " (%s)\n", istate->tnpc, get_symtab_entry(istate->tnpc));
printf("TPC=%#" PRIx64 " (%s)\n", istate->tpc, tpcs);
printf("TNPC=%#" PRIx64 " (%s)\n", istate->tnpc, tnpcs);
}
 
/** Handle instruction_access_exception. (0x8) */
void instruction_access_exception(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle instruction_access_error. (0xa) */
void instruction_access_error(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle illegal_instruction. (0x10) */
void illegal_instruction(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle privileged_opcode. (0x11) */
void privileged_opcode(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle unimplemented_LDD. (0x12) */
void unimplemented_LDD(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle unimplemented_STD. (0x13) */
void unimplemented_STD(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle fp_disabled. (0x20) */
113,9 → 118,9
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
#endif
}
 
122,98 → 127,98
/** Handle fp_exception_ieee_754. (0x21) */
void fp_exception_ieee_754(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle fp_exception_other. (0x22) */
void fp_exception_other(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle tag_overflow. (0x23) */
void tag_overflow(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle division_by_zero. (0x28) */
void division_by_zero(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle data_access_exception. (0x30) */
void data_access_exception(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
dump_sfsr_and_sfar();
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle data_access_error. (0x32) */
void data_access_error(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle mem_address_not_aligned. (0x34) */
void mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle LDDF_mem_address_not_aligned. (0x35) */
void LDDF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle STDF_mem_address_not_aligned. (0x36) */
void STDF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle privileged_action. (0x37) */
void privileged_action(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle LDQF_mem_address_not_aligned. (0x38) */
void LDQF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Handle STQF_mem_address_not_aligned. (0x39) */
void STQF_mem_address_not_aligned(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "%s\n", __func__);
fault_if_from_uspace(istate, "%s.", __func__);
dump_istate(istate);
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** @}
/branches/arm/kernel/arch/sparc64/src/trap/interrupt.c
67,11 → 67,19
*/
void interrupt(int n, istate_t *istate)
{
uint64_t status;
uint64_t intrcv;
uint64_t data0;
status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0);
if (status & (!INTR_DISPATCH_STATUS_BUSY))
panic("Interrupt Dispatch Status busy bit not set.");
 
intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);
data0 = asi_u64_read(ASI_UDB_INTR_R, ASI_UDB_INTR_R_DATA_0);
#if defined (US)
data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0);
#elif defined (US3)
data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0);
#endif
 
irq_t *irq = irq_dispatch_and_lock(data0);
if (irq) {
78,7 → 86,13
/*
* The IRQ handler was found.
*/
irq->handler(irq, irq->arg);
irq->handler(irq);
/*
* See if there is a clear-interrupt-routine and call it.
*/
if (irq->cir) {
irq->cir(irq->cir_arg, irq->inr);
}
spinlock_unlock(&irq->lock);
} else if (data0 > config.base) {
/*
98,7 → 112,7
*/
#ifdef CONFIG_DEBUG
printf("cpu%u: spurious interrupt (intrcv=%#" PRIx64
", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0);
", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0);
#endif
}
 
/branches/arm/kernel/arch/sparc64/src/start.S
27,6 → 27,7
#
 
#include <arch/arch.h>
#include <arch/cpu.h>
#include <arch/regdef.h>
#include <arch/boot/boot.h>
#include <arch/stack.h>
47,6 → 48,16
#define BSP_FLAG 1
 
/*
* 2^PHYSMEM_ADDR_SIZE is the size of the physical address space on
* a given processor.
*/
#if defined (US)
#define PHYSMEM_ADDR_SIZE 41
#elif defined (US3)
#define PHYSMEM_ADDR_SIZE 43
#endif
 
/*
* Here is where the kernel is passed control from the boot loader.
*
* The registers are expected to be in this state:
67,11 → 78,13
and %o0, %l0, %l7 ! l7 <= bootstrap processor?
andn %o0, %l0, %l6 ! l6 <= start of physical memory
 
! Get bits 40:13 of physmem_base.
! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base.
srlx %l6, 13, %l5
sllx %l5, 13 + (63 - 40), %l5
srlx %l5, 63 - 40, %l5 ! l5 <= physmem_base[40:13]
! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13]
sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5
srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5
 
/*
* Setup basic runtime environment.
*/
83,6 → 96,8
! consistent
wrpr %g0, NWINDOWS - 1, %cleanwin ! prevent needless clean_window
! traps for kernel
wrpr %g0, 0, %wstate ! use default spill/fill trap
 
wrpr %g0, 0, %tl ! TL = 0, primary context
! register is used
244,7 → 259,8
 
/*
* Precompute kernel 8K TLB data template.
* %l5 contains starting physical address bits [40:13]
* %l5 contains starting physical address
* bits [(PHYSMEM_ADDR_SIZE - 1):13]
*/
sethi %hi(kernel_8k_tlb_data_template), %l4
ldx [%l4 + %lo(kernel_8k_tlb_data_template)], %l3
278,19 → 294,36
/* Not reached. */
 
0:
ba 0b
ba %xcc, 0b
nop
 
 
1:
#ifdef CONFIG_SMP
/*
* Determine the width of the MID and save its mask to %g3. The width
* is
* * 5 for US and US-IIIi,
* * 10 for US3 except US-IIIi.
*/
#if defined(US)
mov 0x1f, %g3
#elif defined(US3)
mov 0x3ff, %g3
rdpr %ver, %g2
sllx %g2, 16, %g2
srlx %g2, 48, %g2
cmp %g2, IMPL_ULTRASPARCIII_I
move %xcc, 0x1f, %g3
#endif
 
/*
* Read MID from the processor.
*/
1:
ldxa [%g0] ASI_UPA_CONFIG, %g1
srlx %g1, UPA_CONFIG_MID_SHIFT, %g1
and %g1, UPA_CONFIG_MID_MASK, %g1
ldxa [%g0] ASI_ICBUS_CONFIG, %g1
srlx %g1, ICBUS_CONFIG_MID_SHIFT, %g1
and %g1, %g3, %g1
 
#ifdef CONFIG_SMP
/*
* Active loop for APs until the BSP picks them up. A processor cannot
* leave the loop until the global variable 'waking_up_mid' equals its
300,7 → 333,7
2:
ldx [%g2], %g3
cmp %g3, %g1
bne 2b
bne %xcc, 2b
nop
 
/*
319,7 → 352,7
#endif
0:
ba 0b
ba %xcc, 0b
nop
 
 
348,10 → 381,31
.quad 0
 
/*
* This variable is used by the fast_data_MMU_miss trap handler. In runtime, it
* is further modified to reflect the starting address of physical memory.
* The fast_data_access_mmu_miss_data_hi label and the end_of_identity and
* kernel_8k_tlb_data_template variables are meant to stay together,
* aligned on 16B boundary.
*/
.global fast_data_access_mmu_miss_data_hi
.global end_of_identity
.global kernel_8k_tlb_data_template
 
.align 16
/*
* This label is used by the fast_data_access_MMU_miss trap handler.
*/
fast_data_access_mmu_miss_data_hi:
/*
* This variable is used by the fast_data_access_MMU_miss trap handler.
* In runtime, it is modified to contain the address of the end of physical
* memory.
*/
end_of_identity:
.quad -1
/*
* This variable is used by the fast_data_access_MMU_miss trap handler.
* In runtime, it is further modified to reflect the starting address of
* physical memory.
*/
kernel_8k_tlb_data_template:
#ifdef CONFIG_VIRT_IDX_DCACHE
.quad ((1 << TTE_V_SHIFT) | (PAGESIZE_8K << TTE_SIZE_SHIFT) | TTE_CP | \
/branches/arm/kernel/arch/sparc64/src/console.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
37,14 → 37,8
 
#include <arch/drivers/scr.h>
#include <arch/drivers/kbd.h>
 
#ifdef CONFIG_Z8530
#include <genarch/kbd/z8530.h>
#endif
#ifdef CONFIG_NS16550
#include <genarch/kbd/ns16550.h>
#endif
 
#include <arch/drivers/sgcn.h>
#include <genarch/srln/srln.h>
#include <console/chardev.h>
#include <console/console.h>
#include <arch/asm.h>
54,92 → 48,101
#include <genarch/ofw/ofw_tree.h>
#include <arch.h>
#include <panic.h>
#include <string.h>
#include <print.h>
 
#define KEYBOARD_POLL_PAUSE 50000 /* 50ms */
 
/** Initialize kernel console to use framebuffer and keyboard directly. */
void standalone_sparc64_console_init(void)
/**
* Initialize kernel console to use framebuffer and keyboard directly.
* Called on UltraSPARC machines with standard keyboard and framebuffer.
*
* @param aliases the "/aliases" OBP node
*/
static void standard_console_init(ofw_tree_node_t *aliases)
{
stdin = NULL;
 
ofw_tree_node_t *aliases;
ofw_tree_property_t *prop;
ofw_tree_node_t *screen;
ofw_tree_node_t *keyboard;
#ifdef CONFIG_FB
ofw_tree_property_t *prop_scr = ofw_tree_getprop(aliases, "screen");
if (!prop_scr)
panic("Cannot find property 'screen'.");
if (!prop_scr->value)
panic("Cannot find screen alias.");
ofw_tree_node_t *screen = ofw_tree_lookup(prop_scr->value);
if (!screen)
panic("Cannot find %s.", prop_scr->value);
aliases = ofw_tree_lookup("/aliases");
if (!aliases)
panic("Can't find /aliases.\n");
prop = ofw_tree_getprop(aliases, "screen");
if (!prop)
panic("Can't find property \"screen\".\n");
if (!prop->value)
panic("Can't find screen alias.\n");
screen = ofw_tree_lookup(prop->value);
if (!screen)
panic("Can't find %s\n", prop->value);
 
scr_init(screen);
#endif
 
prop = ofw_tree_getprop(aliases, "keyboard");
if (!prop)
panic("Can't find property \"keyboard\".\n");
if (!prop->value)
panic("Can't find keyboard alias.\n");
keyboard = ofw_tree_lookup(prop->value);
#ifdef CONFIG_SUN_KBD
ofw_tree_property_t *prop_kbd = ofw_tree_getprop(aliases, "keyboard");
if (!prop_kbd)
panic("Cannot find property 'keyboard'.");
if (!prop_kbd->value)
panic("Cannot find keyboard alias.");
ofw_tree_node_t *keyboard = ofw_tree_lookup(prop_kbd->value);
if (!keyboard)
panic("Can't find %s\n", prop->value);
 
panic("Cannot find %s.", prop_kbd->value);
kbd_init(keyboard);
#endif
}
 
/** Kernel thread for polling keyboard.
*
* @param arg Ignored.
*/
void kkbdpoll(void *arg)
/** Initilize I/O on the Serengeti machine. */
static void serengeti_init(void)
{
thread_detach(THREAD);
 
#ifdef CONFIG_Z8530
if (kbd_type == KBD_Z8530) {
/*
* The z8530 driver is interrupt-driven.
*/
return;
#ifdef CONFIG_SGCN_KBD
sgcn_instance_t *sgcn_instance = sgcnin_init();
if (sgcn_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
sgcnin_wire(sgcn_instance, srln);
}
}
#endif
#ifdef CONFIG_SGCN_PRN
sgcnout_init();
#endif
}
 
while (1) {
#ifdef CONFIG_NS16550
if (kbd_type == KBD_NS16550)
ns16550_poll();
#endif
thread_usleep(KEYBOARD_POLL_PAUSE);
/**
* Initialize input/output. Auto-detects the type of machine
* and calls the appropriate I/O init routine.
*/
void standalone_sparc64_console_init(void)
{
ofw_tree_node_t *aliases;
ofw_tree_property_t *prop;
aliases = ofw_tree_lookup("/aliases");
if (!aliases)
panic("Cannot find '/aliases'.");
/* "def-cn" = "default console" */
prop = ofw_tree_getprop(aliases, "def-cn");
if ((!prop) || (!prop->value) || (str_cmp(prop->value, "/sgcn") != 0)) {
standard_console_init(aliases);
} else {
serengeti_init();
}
}
 
 
/** Acquire console back for kernel
*
*/
void arch_grab_console(void)
{
switch (kbd_type) {
#ifdef CONFIG_Z8530
case KBD_Z8530:
z8530_grab();
break;
#ifdef CONFIG_FB
scr_redraw();
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
ns16550_grab();
break;
#ifdef CONFIG_SGCN_KBD
sgcn_grab();
#endif
default:
break;
}
}
 
/** Return console to userspace
147,20 → 150,9
*/
void arch_release_console(void)
{
switch (kbd_type) {
#ifdef CONFIG_Z8530
case KBD_Z8530:
z8530_release();
break;
#ifdef CONFIG_SGCN_KBD
sgcn_release();
#endif
#ifdef CONFIG_NS16550
case KBD_NS16550:
ns16550_release();
break;
#endif
default:
break;
}
}
 
/** @}
/branches/arm/kernel/arch/sparc64/src/sparc64.c
37,7 → 37,6
#include <config.h>
#include <arch/trap/trap.h>
#include <arch/console.h>
#include <proc/thread.h>
#include <console/console.h>
#include <arch/boot/boot.h>
#include <arch/arch.h>
47,10 → 46,11
#include <genarch/ofw/ofw_tree.h>
#include <userspace.h>
#include <ddi/irq.h>
#include <string.h>
 
bootinfo_t bootinfo;
 
/** Perform sparc64 specific initialization before main_bsp() is called. */
/** Perform sparc64-specific initialization before main_bsp() is called. */
void arch_pre_main(void)
{
/* Copy init task info. */
61,6 → 61,8
for (i = 0; i < bootinfo.taskmap.count; i++) {
init.tasks[i].addr = (uintptr_t) bootinfo.taskmap.tasks[i].addr;
init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
bootinfo.taskmap.tasks[i].name);
}
/* Copy boot allocations info. */
86,8 → 88,6
* But we only create 128 buckets.
*/
irq_init(1 << 11, 128);
standalone_sparc64_console_init();
}
}
 
101,18 → 101,7
 
void arch_post_smp_init(void)
{
static thread_t *t = NULL;
 
 
if (!t) {
/*
* Create thread that polls keyboard.
*/
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("cannot create kkbdpoll\n");
thread_ready(t);
}
standalone_sparc64_console_init();
}
 
/** Calibrate delay loop.
161,5 → 150,19
while (1);
}
 
/** 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/arm/kernel/arch/sparc64/src/ddi/ddi.c
41,7 → 41,7
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param ioaddr Starting I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
/branches/arm/kernel/arch/sparc64/src/cpu/cpu.c
32,12 → 32,46
/** @file
*/
 
#include <arch/cpu_family.h>
#include <cpu.h>
#include <arch.h>
#include <genarch/ofw/ofw_tree.h>
#include <arch/drivers/tick.h>
#include <print.h>
#include <arch/cpu_node.h>
 
/**
* Finds out the clock frequency of the current CPU.
*
* @param node node representing the current CPU in the OFW tree
* @return clock frequency if "node" is the current CPU and no error
* occurs, -1 if "node" is not the current CPU or on error
*/
static int find_cpu_frequency(ofw_tree_node_t *node)
{
ofw_tree_property_t *prop;
uint32_t mid;
 
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */
prop = ofw_tree_getprop(node, "upa-portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "portid");
if ((!prop) || (!prop->value))
prop = ofw_tree_getprop(node, "cpuid");
if (prop && prop->value) {
mid = *((uint32_t *) prop->value);
if (mid == CPU->arch.mid) {
prop = ofw_tree_getprop(node, "clock-frequency");
if (prop && prop->value) {
return *((uint32_t *) prop->value);
}
}
}
return -1;
}
 
/** Perform sparc64 specific initialization of the processor structure for the
* current processor.
*/
44,34 → 78,37
void cpu_arch_init(void)
{
ofw_tree_node_t *node;
uint32_t mid;
uint32_t clock_frequency = 0;
upa_config_t upa_config;
upa_config.value = upa_config_read();
CPU->arch.mid = upa_config.mid;
CPU->arch.mid = read_mid();
/*
* Detect processor frequency.
*/
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu");
while (node) {
ofw_tree_property_t *prop;
prop = ofw_tree_getprop(node, "upa-portid");
if (prop && prop->value) {
mid = *((uint32_t *) prop->value);
if (mid == CPU->arch.mid) {
prop = ofw_tree_getprop(node,
"clock-frequency");
if (prop && prop->value)
clock_frequency = *((uint32_t *)
prop->value);
}
if (is_us() || is_us_iii()) {
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu");
while (node) {
int f = find_cpu_frequency(node);
if (f != -1)
clock_frequency = (uint32_t) f;
node = ofw_tree_find_peer_by_device_type(node, "cpu");
}
node = ofw_tree_find_peer_by_device_type(node, "cpu");
} else if (is_us_iv()) {
node = ofw_tree_find_child(cpus_parent(), "cmp");
while (node) {
int f;
f = find_cpu_frequency(
ofw_tree_find_child(node, "cpu@0"));
if (f != -1)
clock_frequency = (uint32_t) f;
f = find_cpu_frequency(
ofw_tree_find_child(node, "cpu@1"));
if (f != -1)
clock_frequency = (uint32_t) f;
node = ofw_tree_find_peer_by_name(node, "cmp");
}
}
 
CPU->arch.clock_frequency = clock_frequency;
tick_init();
}
124,6 → 161,15
case IMPL_ULTRASPARCIII:
impl = "UltraSPARC III";
break;
case IMPL_ULTRASPARCIII_PLUS:
impl = "UltraSPARC III+";
break;
case IMPL_ULTRASPARCIII_I:
impl = "UltraSPARC IIIi";
break;
case IMPL_ULTRASPARCIV:
impl = "UltraSPARC IV";
break;
case IMPL_ULTRASPARCIV_PLUS:
impl = "UltraSPARC IV+";
break;
/branches/arm/kernel/arch/sparc64/src/proc/thread.c
34,9 → 34,8
 
#include <proc/thread.h>
#include <arch/proc/thread.h>
#include <mm/frame.h>
#include <mm/page.h>
#include <arch/mm/page.h>
#include <mm/slab.h>
#include <arch/trap/regwin.h>
#include <align.h>
 
void thr_constructor_arch(thread_t *t)
50,12 → 49,12
void thr_destructor_arch(thread_t *t)
{
if (t->arch.uspace_window_buffer) {
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
/*
* Mind the possible alignment of the userspace window buffer
* belonging to a killed thread.
*/
frame_free(KA2PA(ALIGN_DOWN((uintptr_t)
t->arch.uspace_window_buffer, PAGE_SIZE)));
free((uint8_t *) ALIGN_DOWN(uw_buf, UWB_ALIGNMENT));
}
}
 
67,7 → 66,7
* The thread needs userspace window buffer and the object
* returned from the slab allocator doesn't have any.
*/
t->arch.uspace_window_buffer = frame_alloc(ONE_FRAME, FRAME_KA);
t->arch.uspace_window_buffer = malloc(UWB_ASIZE, 0);
} else {
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer;
 
76,7 → 75,7
* belonging to a killed thread.
*/
t->arch.uspace_window_buffer = (uint8_t *) ALIGN_DOWN(uw_buf,
PAGE_SIZE);
UWB_ASIZE);
}
}
 
/branches/arm/kernel/arch/sparc64/include/byteorder.h
File deleted
/branches/arm/kernel/arch/sparc64/include/context.h
39,7 → 39,7
#include <arch/types.h>
#include <align.h>
 
#define SP_DELTA STACK_WINDOW_SAVE_AREA_SIZE
#define SP_DELTA (STACK_WINDOW_SAVE_AREA_SIZE + STACK_ARG_SAVE_AREA_SIZE)
 
#ifdef context_set
#undef context_set
/branches/arm/kernel/arch/sparc64/include/types.h
46,8 → 46,6
typedef unsigned long uint64_t;
 
typedef uint64_t size_t;
typedef uint64_t count_t;
typedef uint64_t index_t;
 
typedef uint64_t uintptr_t;
typedef uint64_t pfn_t;
57,11 → 55,12
typedef uint64_t unative_t;
typedef int64_t native_t;
 
/**< Formats for uintptr_t, size_t, count_t and index_t */
typedef struct {
} fncptr_t;
 
/**< Formats for uintptr_t, size_t */
#define PRIp "llx"
#define PRIs "llu"
#define PRIc "llu"
#define PRIi "llu"
 
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
#define PRId8 "d"
/branches/arm/kernel/arch/sparc64/include/mm/tlb.h
35,9 → 35,17
#ifndef KERN_sparc64_TLB_H_
#define KERN_sparc64_TLB_H_
 
#if defined (US)
#define ITLB_ENTRY_COUNT 64
#define DTLB_ENTRY_COUNT 64
#define DTLB_MAX_LOCKED_ENTRIES DTLB_ENTRY_COUNT
#endif
 
/** TLB_DSMALL is the only of the three DMMUs that can hold locked entries. */
#if defined (US3)
#define DTLB_MAX_LOCKED_ENTRIES 16
#endif
 
#define MEM_CONTEXT_KERNEL 0
#define MEM_CONTEXT_TEMP 1
 
53,6 → 61,9
/* TLB Demap Operation types. */
#define TLB_DEMAP_PAGE 0
#define TLB_DEMAP_CONTEXT 1
#if defined (US3)
#define TLB_DEMAP_ALL 2
#endif
 
#define TLB_DEMAP_TYPE_SHIFT 6
 
61,6 → 72,18
#define TLB_DEMAP_SECONDARY 1
#define TLB_DEMAP_NUCLEUS 2
 
/* There are more TLBs in one MMU in US3, their codes are defined here. */
#if defined (US3)
/* D-MMU: one small (16-entry) TLB and two big (512-entry) TLBs */
#define TLB_DSMALL 0
#define TLB_DBIG_0 2
#define TLB_DBIG_1 3
/* I-MMU: one small (16-entry) TLB and one big TLB */
#define TLB_ISMALL 0
#define TLB_IBIG 2
#endif
 
#define TLB_DEMAP_CONTEXT_SHIFT 4
 
/* TLB Tag Access shifts */
76,6 → 99,8
#include <arch/asm.h>
#include <arch/barrier.h>
#include <arch/types.h>
#include <arch/register.h>
#include <arch/cpu.h>
 
union tlb_context_reg {
uint64_t v;
90,6 → 115,9
typedef tte_data_t tlb_data_t;
 
/** I-/D-TLB Data Access Address in Alternate Space. */
 
#if defined (US)
 
union tlb_data_access_addr {
uint64_t value;
struct {
98,9 → 126,54
unsigned : 3;
} __attribute__ ((packed));
};
typedef union tlb_data_access_addr tlb_data_access_addr_t;
typedef union tlb_data_access_addr tlb_tag_read_addr_t;
typedef union tlb_data_access_addr dtlb_data_access_addr_t;
typedef union tlb_data_access_addr dtlb_tag_read_addr_t;
typedef union tlb_data_access_addr itlb_data_access_addr_t;
typedef union tlb_data_access_addr itlb_tag_read_addr_t;
 
#elif defined (US3)
 
/*
* In US3, I-MMU and D-MMU have different formats of the data
* access register virtual address. In the corresponding
* structures the member variable for the entry number is
* called "local_tlb_entry" - it contrasts with the "tlb_entry"
* for the US data access register VA structure. The rationale
* behind this is to prevent careless mistakes in the code
* caused by setting only the entry number and not the TLB
* number in the US3 code (when taking the code from US).
*/
 
union dtlb_data_access_addr {
uint64_t value;
struct {
uint64_t : 45;
unsigned : 1;
unsigned tlb_number : 2;
unsigned : 4;
unsigned local_tlb_entry : 9;
unsigned : 3;
} __attribute__ ((packed));
};
typedef union dtlb_data_access_addr dtlb_data_access_addr_t;
typedef union dtlb_data_access_addr dtlb_tag_read_addr_t;
 
union itlb_data_access_addr {
uint64_t value;
struct {
uint64_t : 45;
unsigned : 1;
unsigned tlb_number : 2;
unsigned : 6;
unsigned local_tlb_entry : 7;
unsigned : 3;
} __attribute__ ((packed));
};
typedef union itlb_data_access_addr itlb_data_access_addr_t;
typedef union itlb_data_access_addr itlb_tag_read_addr_t;
 
#endif
 
/** I-/D-TLB Tag Read Register. */
union tlb_tag_read_reg {
uint64_t value;
118,8 → 191,13
uint64_t value;
struct {
uint64_t vpn: 51; /**< Virtual Address bits 63:13. */
#if defined (US)
unsigned : 6; /**< Ignored. */
unsigned type : 1; /**< The type of demap operation. */
#elif defined (US3)
unsigned : 5; /**< Ignored. */
unsigned type: 2; /**< The type of demap operation. */
#endif
unsigned context : 2; /**< Context register selection. */
unsigned : 4; /**< Zero. */
} __attribute__ ((packed));
130,10 → 208,19
union tlb_sfsr_reg {
uint64_t value;
struct {
#if defined (US)
unsigned long : 40; /**< Implementation dependent. */
unsigned asi : 8; /**< ASI. */
unsigned : 2;
unsigned ft : 7; /**< Fault type. */
#elif defined (US3)
unsigned long : 39; /**< Implementation dependent. */
unsigned nf : 1; /**< Non-faulting load. */
unsigned asi : 8; /**< ASI. */
unsigned tm : 1; /**< I-TLB miss. */
unsigned : 3; /**< Reserved. */
unsigned ft : 5; /**< Fault type. */
#endif
unsigned e : 1; /**< Side-effect bit. */
unsigned ct : 2; /**< Context Register selection. */
unsigned pr : 1; /**< Privilege bit. */
144,9 → 231,53
};
typedef union tlb_sfsr_reg tlb_sfsr_reg_t;
 
#if defined (US3)
 
/*
* Functions for determining the number of entries in TLBs. They either return
* a constant value or a value based on the CPU autodetection.
*/
 
/**
* Determine the number of entries in the DMMU's small TLB.
*/
static inline uint16_t tlb_dsmall_size(void)
{
return 16;
}
 
/**
* Determine the number of entries in each DMMU's big TLB.
*/
static inline uint16_t tlb_dbig_size(void)
{
return 512;
}
 
/**
* Determine the number of entries in the IMMU's small TLB.
*/
static inline uint16_t tlb_ismall_size(void)
{
return 16;
}
 
/**
* Determine the number of entries in the IMMU's big TLB.
*/
static inline uint16_t tlb_ibig_size(void)
{
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS)
return 512;
else
return 128;
}
 
#endif
 
/** Read MMU Primary Context Register.
*
* @return Current value of Primary Context Register.
* @return Current value of Primary Context Register.
*/
static inline uint64_t mmu_primary_context_read(void)
{
155,7 → 286,7
 
/** Write MMU Primary Context Register.
*
* @param v New value of Primary Context Register.
* @param v New value of Primary Context Register.
*/
static inline void mmu_primary_context_write(uint64_t v)
{
165,7 → 296,7
 
/** Read MMU Secondary Context Register.
*
* @return Current value of Secondary Context Register.
* @return Current value of Secondary Context Register.
*/
static inline uint64_t mmu_secondary_context_read(void)
{
174,7 → 305,7
 
/** Write MMU Primary Context Register.
*
* @param v New value of Primary Context Register.
* @param v New value of Primary Context Register.
*/
static inline void mmu_secondary_context_write(uint64_t v)
{
182,15 → 313,18
flush_pipeline();
}
 
#if defined (US)
 
/** Read IMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Data Access Register.
* @return Current value of specified IMMU TLB Data Access
* Register.
*/
static inline uint64_t itlb_data_access_read(index_t entry)
static inline uint64_t itlb_data_access_read(size_t entry)
{
tlb_data_access_addr_t reg;
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
199,12 → 333,12
 
/** Write IMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param value Value to be written.
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void itlb_data_access_write(index_t entry, uint64_t value)
static inline void itlb_data_access_write(size_t entry, uint64_t value)
{
tlb_data_access_addr_t reg;
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
214,13 → 348,14
 
/** Read DMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Data Access Register.
* @return Current value of specified DMMU TLB Data Access
* Register.
*/
static inline uint64_t dtlb_data_access_read(index_t entry)
static inline uint64_t dtlb_data_access_read(size_t entry)
{
tlb_data_access_addr_t reg;
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
229,12 → 364,12
 
/** Write DMMU TLB Data Access Register.
*
* @param entry TLB Entry index.
* @param value Value to be written.
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void dtlb_data_access_write(index_t entry, uint64_t value)
static inline void dtlb_data_access_write(size_t entry, uint64_t value)
{
tlb_data_access_addr_t reg;
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_entry = entry;
244,13 → 379,13
 
/** Read IMMU TLB Tag Read Register.
*
* @param entry TLB Entry index.
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Tag Read Register.
* @return Current value of specified IMMU TLB Tag Read Register.
*/
static inline uint64_t itlb_tag_read_read(index_t entry)
static inline uint64_t itlb_tag_read_read(size_t entry)
{
tlb_tag_read_addr_t tag;
itlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_entry = entry;
259,13 → 394,13
 
/** Read DMMU TLB Tag Read Register.
*
* @param entry TLB Entry index.
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Tag Read Register.
* @return Current value of specified DMMU TLB Tag Read Register.
*/
static inline uint64_t dtlb_tag_read_read(index_t entry)
static inline uint64_t dtlb_tag_read_read(size_t entry)
{
tlb_tag_read_addr_t tag;
dtlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_entry = entry;
272,9 → 407,120
return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
}
 
#elif defined (US3)
 
 
/** Read IMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Data Access
* Register.
*/
static inline uint64_t itlb_data_access_read(int tlb, size_t entry)
{
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value);
}
 
/** Write IMMU TLB Data Access Register.
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void itlb_data_access_write(int tlb, size_t entry,
uint64_t value)
{
itlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value);
flush_pipeline();
}
 
/** Read DMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG, TLB_DBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Data Access
* Register.
*/
static inline uint64_t dtlb_data_access_read(int tlb, size_t entry)
{
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value);
}
 
/** Write DMMU TLB Data Access Register.
*
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1)
* @param entry TLB Entry index.
* @param value Value to be written.
*/
static inline void dtlb_data_access_write(int tlb, size_t entry,
uint64_t value)
{
dtlb_data_access_addr_t reg;
reg.value = 0;
reg.tlb_number = tlb;
reg.local_tlb_entry = entry;
asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value);
membar();
}
 
/** Read IMMU TLB Tag Read Register.
*
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG)
* @param entry TLB Entry index.
*
* @return Current value of specified IMMU TLB Tag Read Register.
*/
static inline uint64_t itlb_tag_read_read(int tlb, size_t entry)
{
itlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_number = tlb;
tag.local_tlb_entry = entry;
return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value);
}
 
/** Read DMMU TLB Tag Read Register.
*
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1)
* @param entry TLB Entry index.
*
* @return Current value of specified DMMU TLB Tag Read Register.
*/
static inline uint64_t dtlb_tag_read_read(int tlb, size_t entry)
{
dtlb_tag_read_addr_t tag;
 
tag.value = 0;
tag.tlb_number = tlb;
tag.local_tlb_entry = entry;
return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value);
}
 
#endif
 
 
/** Write IMMU TLB Tag Access Register.
*
* @param v Value to be written.
* @param v Value to be written.
*/
static inline void itlb_tag_access_write(uint64_t v)
{
284,7 → 530,7
 
/** Read IMMU TLB Tag Access Register.
*
* @return Current value of IMMU TLB Tag Access Register.
* @return Current value of IMMU TLB Tag Access Register.
*/
static inline uint64_t itlb_tag_access_read(void)
{
293,7 → 539,7
 
/** Write DMMU TLB Tag Access Register.
*
* @param v Value to be written.
* @param v Value to be written.
*/
static inline void dtlb_tag_access_write(uint64_t v)
{
303,7 → 549,7
 
/** Read DMMU TLB Tag Access Register.
*
* @return Current value of DMMU TLB Tag Access Register.
* @return Current value of DMMU TLB Tag Access Register.
*/
static inline uint64_t dtlb_tag_access_read(void)
{
313,7 → 559,7
 
/** Write IMMU TLB Data in Register.
*
* @param v Value to be written.
* @param v Value to be written.
*/
static inline void itlb_data_in_write(uint64_t v)
{
323,7 → 569,7
 
/** Write DMMU TLB Data in Register.
*
* @param v Value to be written.
* @param v Value to be written.
*/
static inline void dtlb_data_in_write(uint64_t v)
{
333,7 → 579,7
 
/** Read ITLB Synchronous Fault Status Register.
*
* @return Current content of I-SFSR register.
* @return Current content of I-SFSR register.
*/
static inline uint64_t itlb_sfsr_read(void)
{
342,7 → 588,7
 
/** Write ITLB Synchronous Fault Status Register.
*
* @param v New value of I-SFSR register.
* @param v New value of I-SFSR register.
*/
static inline void itlb_sfsr_write(uint64_t v)
{
352,7 → 598,7
 
/** Read DTLB Synchronous Fault Status Register.
*
* @return Current content of D-SFSR register.
* @return Current content of D-SFSR register.
*/
static inline uint64_t dtlb_sfsr_read(void)
{
361,7 → 607,7
 
/** Write DTLB Synchronous Fault Status Register.
*
* @param v New value of D-SFSR register.
* @param v New value of D-SFSR register.
*/
static inline void dtlb_sfsr_write(uint64_t v)
{
371,7 → 617,7
 
/** Read DTLB Synchronous Fault Address Register.
*
* @return Current content of D-SFAR register.
* @return Current content of D-SFAR register.
*/
static inline uint64_t dtlb_sfar_read(void)
{
380,10 → 626,11
 
/** Perform IMMU TLB Demap Operation.
*
* @param type Selects between context and page demap.
* @param type Selects between context and page demap (and entire MMU
* demap on US3).
* @param context_encoding Specifies which Context register has Context ID for
* demap.
* @param page Address which is on the page to be demapped.
* demap.
* @param page Address which is on the page to be demapped.
*/
static inline void itlb_demap(int type, int context_encoding, uintptr_t page)
{
397,18 → 644,19
da.context = context_encoding;
da.vpn = pg.vpn;
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the
* address within the
* ASI */
/* da.value is the address within the ASI */
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0);
 
flush_pipeline();
}
 
/** Perform DMMU TLB Demap Operation.
*
* @param type Selects between context and page demap.
* @param type Selects between context and page demap (and entire MMU
* demap on US3).
* @param context_encoding Specifies which Context register has Context ID for
* demap.
* @param page Address which is on the page to be demapped.
* demap.
* @param page Address which is on the page to be demapped.
*/
static inline void dtlb_demap(int type, int context_encoding, uintptr_t page)
{
422,17 → 670,17
da.context = context_encoding;
da.vpn = pg.vpn;
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the
* address within the
* ASI */
/* da.value is the address within the ASI */
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0);
 
membar();
}
 
extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate);
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate);
extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate);
extern void fast_instruction_access_mmu_miss(unative_t, istate_t *);
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *);
extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *);
 
extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable);
extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool);
 
extern void dump_sfsr_and_sfar(void);
 
/branches/arm/kernel/arch/sparc64/include/mm/tsb.h
107,13 → 107,62
asi_u64_write(ASI_DMMU, VA_DMMU_TSB_BASE, v);
}
 
#if defined (US3)
 
/** Write DTSB Primary Extension register.
*
* @param v New content of the DTSB Primary Extension register.
*/
static inline void dtsb_primary_extension_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_PRIMARY_EXTENSION, v);
}
 
/** Write DTSB Secondary Extension register.
*
* @param v New content of the DTSB Secondary Extension register.
*/
static inline void dtsb_secondary_extension_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_SECONDARY_EXTENSION, v);
}
 
/** Write DTSB Nucleus Extension register.
*
* @param v New content of the DTSB Nucleus Extension register.
*/
static inline void dtsb_nucleus_extension_write(uint64_t v)
{
asi_u64_write(ASI_DMMU, VA_DMMU_NUCLEUS_EXTENSION, v);
}
 
/** Write ITSB Primary Extension register.
*
* @param v New content of the ITSB Primary Extension register.
*/
static inline void itsb_primary_extension_write(uint64_t v)
{
asi_u64_write(ASI_IMMU, VA_IMMU_PRIMARY_EXTENSION, v);
}
 
/** Write ITSB Nucleus Extension register.
*
* @param v New content of the ITSB Nucleus Extension register.
*/
static inline void itsb_nucleus_extension_write(uint64_t v)
{
asi_u64_write(ASI_IMMU, VA_IMMU_NUCLEUS_EXTENSION, v);
}
 
#endif
 
/* Forward declarations. */
struct as;
struct pte;
 
extern void tsb_invalidate(struct as *as, uintptr_t page, count_t pages);
extern void itsb_pte_copy(struct pte *t, index_t index);
extern void dtsb_pte_copy(struct pte *t, index_t index, bool ro);
extern void tsb_invalidate(struct as *as, uintptr_t page, size_t pages);
extern void itsb_pte_copy(struct pte *t, size_t index);
extern void dtsb_pte_copy(struct pte *t, size_t index, bool ro);
 
#endif /* !def __ASM__ */
 
/branches/arm/kernel/arch/sparc64/include/mm/frame.h
59,8 → 59,13
union frame_address {
uintptr_t address;
struct {
#if defined (US)
unsigned : 23;
uint64_t pfn : 28; /**< Physical Frame Number. */
#elif defined (US3)
unsigned : 21;
uint64_t pfn : 30; /**< Physical Frame Number. */
#endif
unsigned offset : 13; /**< Offset. */
} __attribute__ ((packed));
};
68,6 → 73,8
typedef union frame_address frame_address_t;
 
extern uintptr_t last_frame;
extern uintptr_t end_of_identity;
 
extern void frame_arch_init(void);
#define physmem_print()
 
/branches/arm/kernel/arch/sparc64/include/mm/tte.h
50,6 → 50,7
 
#include <arch/types.h>
 
/* TTE tag's VA_tag field contains bits <63:VA_TAG_PAGE_SHIFT> of the VA */
#define VA_TAG_PAGE_SHIFT 22
 
/** Translation Table Entry - Tag. */
75,8 → 76,13
unsigned nfo : 1; /**< No-Fault-Only. */
unsigned ie : 1; /**< Invert Endianness. */
unsigned soft2 : 9; /**< Software defined field. */
#if defined (US)
unsigned diag : 9; /**< Diagnostic data. */
unsigned pfn : 28; /**< Physical Address bits, bits 40:13. */
#elif defined (US3)
unsigned : 7; /**< Reserved. */
unsigned pfn : 30; /**< Physical Address bits, bits 42:13 */
#endif
unsigned soft : 6; /**< Software defined field. */
unsigned l : 1; /**< Lock. */
unsigned cp : 1; /**< Cacheable in physically indexed cache. */
/branches/arm/kernel/arch/sparc64/include/mm/cache_spec.h
38,19 → 38,20
/*
* The following macros are valid for the following processors:
*
* UltraSPARC, UltraSPARC II, UltraSPARC IIi
* UltraSPARC, UltraSPARC II, UltraSPARC IIi, UltraSPARC III,
* UltraSPARC III+, UltraSPARC IV, UltraSPARC IV+
*
* Should we support other UltraSPARC processors, we need to make sure that
* the macros are defined correctly for them.
*/
 
#if defined (US)
#define DCACHE_SIZE (16 * 1024)
#elif defined (US3)
#define DCACHE_SIZE (64 * 1024)
#endif
#define DCACHE_LINE_SIZE 32
 
#define ICACHE_SIZE (16 * 1024)
#define ICACHE_WAYS 2
#define ICACHE_LINE_SIZE 32
 
#endif
 
/** @}
/branches/arm/kernel/arch/sparc64/include/mm/mmu.h
35,8 → 35,10
#ifndef KERN_sparc64_MMU_H_
#define KERN_sparc64_MMU_H_
 
#if defined(US)
/* LSU Control Register ASI. */
#define ASI_LSU_CONTROL_REG 0x45 /**< Load/Store Unit Control Register. */
#endif
 
/* I-MMU ASIs. */
#define ASI_IMMU 0x50
52,7 → 54,12
#define VA_IMMU_SFSR 0x18 /**< IMMU sync fault status register. */
#define VA_IMMU_TSB_BASE 0x28 /**< IMMU TSB base register. */
#define VA_IMMU_TAG_ACCESS 0x30 /**< IMMU TLB tag access register. */
#if defined (US3)
#define VA_IMMU_PRIMARY_EXTENSION 0x48 /**< IMMU TSB primary extension register */
#define VA_IMMU_NUCLEUS_EXTENSION 0x58 /**< IMMU TSB nucleus extension register */
#endif
 
 
/* D-MMU ASIs. */
#define ASI_DMMU 0x58
#define ASI_DMMU_TSB_8KB_PTR_REG 0x59
73,6 → 80,11
#define VA_DMMU_TAG_ACCESS 0x30 /**< DMMU TLB tag access register. */
#define VA_DMMU_VA_WATCHPOINT_REG 0x38 /**< DMMU VA data watchpoint register. */
#define VA_DMMU_PA_WATCHPOINT_REG 0x40 /**< DMMU PA data watchpoint register. */
#if defined (US3)
#define VA_DMMU_PRIMARY_EXTENSION 0x48 /**< DMMU TSB primary extension register */
#define VA_DMMU_SECONDARY_EXTENSION 0x50 /**< DMMU TSB secondary extension register */
#define VA_DMMU_NUCLEUS_EXTENSION 0x58 /**< DMMU TSB nucleus extension register */
#endif
 
#ifndef __ASM__
 
80,6 → 92,7
#include <arch/barrier.h>
#include <arch/types.h>
 
#if defined(US)
/** LSU Control Register. */
typedef union {
uint64_t value;
100,6 → 113,7
} __attribute__ ((packed));
} lsu_cr_reg_t;
#endif /* US */
 
#endif /* !def __ASM__ */
 
/branches/arm/kernel/arch/sparc64/include/mm/cache.h
38,15 → 38,6
#include <mm/page.h>
#include <mm/frame.h>
 
#define dcache_flush_page(p) \
dcache_flush_color(PAGE_COLOR((p)))
#define dcache_flush_frame(p, f) \
dcache_flush_tag(PAGE_COLOR((p)), ADDR2PFN((f)));
 
extern void dcache_flush(void);
extern void dcache_flush_color(int c);
extern void dcache_flush_tag(int c, pfn_t tag);
 
#endif
 
/** @}
/branches/arm/kernel/arch/sparc64/include/trap/trap_table.h
100,7 → 100,7
 
.macro PREEMPTIBLE_HANDLER f
sethi %hi(\f), %g1
b preemptible_handler
ba %xcc, preemptible_handler
or %g1, %lo(\f), %g1
.endm
 
/branches/arm/kernel/arch/sparc64/include/trap/mmu.h
103,17 → 103,20
* Note that branch-delay slots are used in order to save space.
*/
0:
mov VA_DMMU_TAG_ACCESS, %g1
ldxa [%g1] ASI_DMMU, %g1 ! read the faulting Context and VPN
sethi %hi(fast_data_access_mmu_miss_data_hi), %g7
wr %g0, ASI_DMMU, %asi
ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1 ! read the faulting Context and VPN
set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
andcc %g1, %g2, %g3 ! get Context
bnz 0f ! Context is non-zero
bnz %xcc, 0f ! Context is non-zero
andncc %g1, %g2, %g3 ! get page address into %g3
bz 0f ! page address is zero
bz %xcc, 0f ! page address is zero
ldx [%g7 + %lo(end_of_identity)], %g4
cmp %g3, %g4
bgeu %xcc, 0f
 
sethi %hi(kernel_8k_tlb_data_template), %g2
ldx [%g2 + %lo(kernel_8k_tlb_data_template)], %g2
or %g3, %g2, %g2
ldx [%g7 + %lo(kernel_8k_tlb_data_template)], %g2
add %g3, %g2, %g2
stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG ! identity map the kernel page
retry
 
138,8 → 141,7
* Read the Tag Access register for the higher-level handler.
* This is necessary to survive nested DTLB misses.
*/
mov VA_DMMU_TAG_ACCESS, %g2
ldxa [%g2] ASI_DMMU, %g2
ldxa [VA_DMMU_TAG_ACCESS] %asi, %g2
 
/*
* g2 will be passed as an argument to fast_data_access_mmu_miss().
/branches/arm/kernel/arch/sparc64/include/trap/interrupt.h
49,21 → 49,43
 
 
/* Interrupt ASI registers. */
#define ASI_UDB_INTR_W 0x77
#define ASI_INTR_W 0x77
#define ASI_INTR_DISPATCH_STATUS 0x48
#define ASI_UDB_INTR_R 0x7f
#define ASI_INTR_R 0x7f
#define ASI_INTR_RECEIVE 0x49
 
/* VA's used with ASI_UDB_INTR_W register. */
/* VA's used with ASI_INTR_W register. */
#if defined (US)
#define ASI_UDB_INTR_W_DATA_0 0x40
#define ASI_UDB_INTR_W_DATA_1 0x50
#define ASI_UDB_INTR_W_DATA_2 0x60
#define ASI_UDB_INTR_W_DISPATCH 0x70
#elif defined (US3)
#define VA_INTR_W_DATA_0 0x40
#define VA_INTR_W_DATA_1 0x48
#define VA_INTR_W_DATA_2 0x50
#define VA_INTR_W_DATA_3 0x58
#define VA_INTR_W_DATA_4 0x60
#define VA_INTR_W_DATA_5 0x68
#define VA_INTR_W_DATA_6 0x80
#define VA_INTR_W_DATA_7 0x88
#endif
#define VA_INTR_W_DISPATCH 0x70
 
/* VA's used with ASI_UDB_INTR_R register. */
/* VA's used with ASI_INTR_R register. */
#if defined(US)
#define ASI_UDB_INTR_R_DATA_0 0x40
#define ASI_UDB_INTR_R_DATA_1 0x50
#define ASI_UDB_INTR_R_DATA_2 0x60
#elif defined (US3)
#define VA_INTR_R_DATA_0 0x40
#define VA_INTR_R_DATA_1 0x48
#define VA_INTR_R_DATA_2 0x50
#define VA_INTR_R_DATA_3 0x58
#define VA_INTR_R_DATA_4 0x60
#define VA_INTR_R_DATA_5 0x68
#define VA_INTR_R_DATA_6 0x80
#define VA_INTR_R_DATA_7 0x88
#endif
 
/* Shifts in the Interrupt Vector Dispatch virtual address. */
#define INTR_VEC_DISPATCH_MID_SHIFT 14
/branches/arm/kernel/arch/sparc64/include/trap/regwin.h
39,6 → 39,7
 
#include <arch/stack.h>
#include <arch/arch.h>
#include <align.h>
 
#define TT_CLEAN_WINDOW 0x24
#define TT_SPILL_0_NORMAL 0x80 /* kernel spills */
72,6 → 73,11
#define I6_OFFSET 112
#define I7_OFFSET 120
 
/* Uspace Window Buffer constants. */
#define UWB_SIZE ((NWINDOWS - 1) * STACK_WINDOW_SAVE_AREA_SIZE)
#define UWB_ALIGNMENT 1024
#define UWB_ASIZE ALIGN_UP(UWB_SIZE, UWB_ALIGNMENT)
 
#ifdef __ASM__
 
/*
/branches/arm/kernel/arch/sparc64/include/atomic.h
123,7 → 123,7
"ldx %0, %2\n"
"brz %2, 0b\n"
"nop\n"
"ba 1b\n"
"ba %xcc, 1b\n"
"nop\n"
"2:\n"
: "+m" (*((uint64_t *) x)), "+r" (tmp1), "+r" (tmp2) : "r" (0)
/branches/arm/kernel/arch/sparc64/include/drivers/z8530.h
File deleted
/branches/arm/kernel/arch/sparc64/include/drivers/ns16550.h
File deleted
/branches/arm/kernel/arch/sparc64/include/drivers/sgcn.h
0,0 → 1,134
/*
* Copyright (c) 2008 Pavel Rimsky
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_SGCN_H_
#define KERN_sparc64_SGCN_H_
 
#include <arch/types.h>
#include <console/chardev.h>
#include <proc/thread.h>
 
/* number of bytes in the TOC magic, including the NULL-terminator */
#define TOC_MAGIC_BYTES 8
 
/* number of bytes in the TOC key, including the NULL-terminator */
#define TOC_KEY_SIZE 8
 
/* maximum number of entries in the SRAM table of contents */
#define MAX_TOC_ENTRIES 32
 
/* number of bytes in the SGCN buffer magic, including the NULL-terminator */
#define SGCN_MAGIC_BYTES 4
 
/**
* Entry in the SRAM table of contents. Describes one segment of the SRAM
* which serves a particular purpose (e.g. OBP serial console, Solaris serial
* console, Solaris mailbox,...).
*/
typedef struct {
/** key (e.g. "OBPCONS", "SOLCONS", "SOLMBOX",...) */
char key[TOC_KEY_SIZE];
/** size of the segment in bytes */
uint32_t size;
/** offset of the segment within SRAM */
uint32_t offset;
} __attribute ((packed)) toc_entry_t;
 
/**
* SRAM table of contents. Describes all segments within the SRAM.
*/
typedef struct {
/** hard-wired to "TOCSRAM" */
char magic[TOC_MAGIC_BYTES];
/** we don't need this */
char unused[8];
/** TOC entries */
toc_entry_t keys[MAX_TOC_ENTRIES];
} __attribute__ ((packed)) iosram_toc_t;
 
/**
* SGCN buffer header. It is placed at the very beginning of the SGCN
* buffer.
*/
typedef struct {
/** hard-wired to "CON" */
char magic[SGCN_MAGIC_BYTES];
/** we don't need this */
char unused[8];
/** offset within the SGCN buffer of the input buffer start */
uint32_t in_begin;
/** offset within the SGCN buffer of the input buffer end */
uint32_t in_end;
/** offset within the SGCN buffer of the input buffer read pointer */
uint32_t in_rdptr;
/** offset within the SGCN buffer of the input buffer write pointer */
uint32_t in_wrptr;
 
/** offset within the SGCN buffer of the output buffer start */
uint32_t out_begin;
/** offset within the SGCN buffer of the output buffer end */
uint32_t out_end;
/** offset within the SGCN buffer of the output buffer read pointer */
uint32_t out_rdptr;
/** offset within the SGCN buffer of the output buffer write pointer */
uint32_t out_wrptr;
} __attribute__ ((packed)) sgcn_buffer_header_t;
 
typedef struct {
thread_t *thread;
indev_t *srlnin;
} sgcn_instance_t;
 
extern void sgcn_grab(void);
extern void sgcn_release(void);
extern sgcn_instance_t *sgcnin_init(void);
extern void sgcnin_wire(sgcn_instance_t *, indev_t *);
extern void sgcnout_init(void);
 
#endif
 
/** @}
*/
/branches/arm/kernel/arch/sparc64/include/drivers/kbd.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
38,14 → 38,6
#include <arch/types.h>
#include <genarch/ofw/ofw_tree.h>
 
typedef enum {
KBD_UNKNOWN,
KBD_Z8530,
KBD_NS16550
} kbd_type_t;
 
extern kbd_type_t kbd_type;
 
extern void kbd_init(ofw_tree_node_t *node);
 
#endif
/branches/arm/kernel/arch/sparc64/include/drivers/scr.h
42,12 → 42,14
SCR_UNKNOWN,
SCR_ATYFB,
SCR_FFB,
SCR_CGSIX
SCR_CGSIX,
SCR_XVR
} scr_type_t;
 
extern scr_type_t scr_type;
 
extern void scr_init(ofw_tree_node_t *node);
extern void scr_redraw(void);
 
#endif
 
/branches/arm/kernel/arch/sparc64/include/drivers/pci.h
51,8 → 51,8
};
 
struct pci_operations {
void (* enable_interrupt)(pci_t *pci, int inr);
void (* clear_interrupt)(pci_t *pci, int inr);
void (* enable_interrupt)(pci_t *, int);
void (* clear_interrupt)(pci_t *, int);
};
 
struct pci {
61,9 → 61,9
volatile uint64_t *reg; /**< Registers including interrupt registers. */
};
 
extern pci_t *pci_init(ofw_tree_node_t *node);
extern void pci_enable_interrupt(pci_t *pci, int inr);
extern void pci_clear_interrupt(pci_t *pci, int inr);
extern pci_t *pci_init(ofw_tree_node_t *);
extern void pci_enable_interrupt(pci_t *, int);
extern void pci_clear_interrupt(void *, int);
 
#endif
 
/branches/arm/kernel/arch/sparc64/include/drivers/fhc.h
44,9 → 44,9
 
extern fhc_t *central_fhc;
 
extern fhc_t *fhc_init(ofw_tree_node_t *node);
extern void fhc_enable_interrupt(fhc_t *fhc, int inr);
extern void fhc_clear_interrupt(fhc_t *fhc, int inr);
extern fhc_t *fhc_init(ofw_tree_node_t *);
extern void fhc_enable_interrupt(fhc_t *, int);
extern void fhc_clear_interrupt(void *, int);
 
#endif
 
/branches/arm/kernel/arch/sparc64/include/memstr.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
/branches/arm/kernel/arch/sparc64/include/boot/boot.h
48,9 → 48,12
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
 
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
typedef struct {
void * addr;
uint32_t size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} utask_t;
 
typedef struct {
/branches/arm/kernel/arch/sparc64/include/asm.h
42,7 → 42,56
#include <arch/register.h>
#include <config.h>
#include <arch/stack.h>
#include <arch/barrier.h>
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
memory_barrier();
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
memory_barrier();
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
memory_barrier();
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
uint8_t rv;
 
rv = *port;
memory_barrier();
 
return rv;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
uint16_t rv;
 
rv = *port;
memory_barrier();
 
return rv;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
uint32_t rv;
 
rv = *port;
memory_barrier();
 
return rv;
}
 
/** Read Processor State register.
*
* @return Value of PSTATE register.
87,6 → 136,28
asm volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0));
}
 
/** Read STICK_compare Register.
*
* @return Value of STICK_compare register.
*/
static inline uint64_t stick_compare_read(void)
{
uint64_t v;
asm volatile ("rd %%asr25, %0\n" : "=r" (v));
return v;
}
 
/** Write STICK_compare Register.
*
* @param v New value of STICK_comapre register.
*/
static inline void stick_compare_write(uint64_t v)
{
asm volatile ("wr %0, %1, %%asr25\n" : : "r" (v), "i" (0));
}
 
/** Read TICK Register.
*
* @return Value of TICK register.
358,15 → 429,6
asm volatile ("wrpr %g0, %g0, %tl\n");
}
 
/** Read UPA_CONFIG register.
*
* @return Value of the UPA_CONFIG register.
*/
static inline uint64_t upa_config_read(void)
{
return asi_u64_read(ASI_UPA_CONFIG, 0);
}
 
extern void cpu_halt(void);
extern void cpu_sleep(void);
extern void asm_delay_loop(const uint32_t usec);
/branches/arm/kernel/arch/sparc64/include/arch.h
41,10 → 41,16
#define ASI_AIUS 0x11 /** Access to secondary context with user privileges. */
#define ASI_NUCLEUS_QUAD_LDD 0x24 /** ASI for 16-byte atomic loads. */
#define ASI_DCACHE_TAG 0x47 /** ASI D-Cache Tag. */
#define ASI_UPA_CONFIG 0x4a /** ASI of the UPA_CONFIG register. */
#define ASI_ICBUS_CONFIG 0x4a /** ASI of the UPA_CONFIG/FIREPLANE_CONFIG register. */
 
#define NWINDOWS 8 /** Number of register window sets. */
 
#ifndef __ASM__
 
extern void arch_pre_main(void);
 
#endif /* __ASM__ */
 
#endif
 
/** @}
/branches/arm/kernel/arch/sparc64/include/cpu_node.h
0,0 → 1,59
/*
* Copyright (c) 2005 Pavel Rimsky
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_CPU_NODE_H_
#define KERN_sparc64_CPU_NODE_H_
 
#include <genarch/ofw/ofw_tree.h>
 
 
/** Finds the parent node of all the CPU nodes (nodes named "cpu" or "cmp").
*
* Depending on the machine type (and possibly the OFW version), CPUs can be
* at "/" or at "/ssm@0,0".
*/
static inline ofw_tree_node_t *cpus_parent(void)
{
ofw_tree_node_t *parent;
parent = ofw_tree_find_child(ofw_tree_lookup("/"), "ssm@0,0");
if (parent == NULL)
parent = ofw_tree_lookup("/");
return parent;
}
 
#endif
 
/** @}
*/
 
/branches/arm/kernel/arch/sparc64/include/cpu_family.h
0,0 → 1,83
/*
* Copyright (c) 2008 Pavel Rimsky
* 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 sparc64
* @{
*/
/** @file
*/
 
#ifndef KERN_sparc64_CPU_FAMILY_H_
#define KERN_sparc64_CPU_FAMILY_H_
 
#include <arch.h>
#include <cpu.h>
#include <arch/register.h>
#include <arch/asm.h>
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US family
*/
static inline bool is_us(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCI) || (impl == IMPL_ULTRASPARCII) ||
(impl == IMPL_ULTRASPARCII_I) || (impl == IMPL_ULTRASPARCII_E);
}
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US-III subfamily
*/
static inline bool is_us_iii(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCIII) ||
(impl == IMPL_ULTRASPARCIII_PLUS) ||
(impl == IMPL_ULTRASPARCIII_I);
}
 
/**
* Find the processor (sub)family.
*
* @return true iff the CPU belongs to the US-IV subfamily
*/
static inline bool is_us_iv(void)
{
int impl = ((ver_reg_t) ver_read()).impl;
return (impl == IMPL_ULTRASPARCIV) || (impl == IMPL_ULTRASPARCIV_PLUS);
}
#endif
 
/** @}
*/
 
/branches/arm/kernel/arch/sparc64/include/fpu_context.h
37,7 → 37,6
 
#include <arch/types.h>
 
#define ARCH_HAS_FPU
#define FPU_CONTEXT_ALIGN 8
 
typedef struct {
/branches/arm/kernel/arch/sparc64/include/barrier.h
82,6 → 82,8
asm volatile ("membar #Sync\n");
}
 
#if defined (US)
 
#define smc_coherence(a) \
{ \
write_barrier(); \
97,6 → 99,22
flush((void *)(a) + i); \
}
 
#elif defined (US3)
 
#define smc_coherence(a) \
{ \
write_barrier(); \
flush_pipeline(); \
}
 
#define smc_coherence_block(a, l) \
{ \
write_barrier(); \
flush_pipeline(); \
}
 
#endif /* defined(US3) */
 
#endif
 
/** @}
/branches/arm/kernel/arch/sparc64/include/regdef.h
55,8 → 55,11
#define WSTATE_NORMAL(n) (n)
#define WSTATE_OTHER(n) ((n) << 3)
 
#define UPA_CONFIG_MID_SHIFT 17
#define UPA_CONFIG_MID_MASK 0x1f
/*
* The following definitions concern the UPA_CONFIG register on US and the
* FIREPLANE_CONFIG register on US3.
*/
#define ICBUS_CONFIG_MID_SHIFT 17
 
#endif
 
/branches/arm/kernel/arch/sparc64/include/register.h
117,23 → 117,6
};
typedef union fprs_reg fprs_reg_t;
 
/** UPA_CONFIG register.
*
* Note that format of this register differs significantly from
* processor version to version. The format defined here
* is the common subset for all supported processor versions.
*/
union upa_config {
uint64_t value;
struct {
uint64_t : 34;
unsigned pcon : 8; /**< Processor configuration. */
unsigned mid : 5; /**< Module (processor) ID register. */
unsigned pcap : 17; /**< Processor capabilities. */
} __attribute__ ((packed));
};
typedef union upa_config upa_config_t;
 
#endif
 
/** @}
/branches/arm/kernel/arch/sparc64/include/cpu.h
35,15 → 35,6
#ifndef KERN_sparc64_CPU_H_
#define KERN_sparc64_CPU_H_
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/register.h>
#include <arch/asm.h>
 
#ifdef CONFIG_SMP
#include <arch/mm/cache.h>
#endif
 
#define MANUF_FUJITSU 0x04
#define MANUF_ULTRASPARC 0x17 /**< UltraSPARC I, UltraSPARC II */
#define MANUF_SUN 0x3e
52,14 → 43,29
#define IMPL_ULTRASPARCII 0x11
#define IMPL_ULTRASPARCII_I 0x12
#define IMPL_ULTRASPARCII_E 0x13
#define IMPL_ULTRASPARCIII 0x15
#define IMPL_ULTRASPARCIII 0x14
#define IMPL_ULTRASPARCIII_PLUS 0x15
#define IMPL_ULTRASPARCIII_I 0x16
#define IMPL_ULTRASPARCIV 0x18
#define IMPL_ULTRASPARCIV_PLUS 0x19
 
#define IMPL_SPARC64V 0x5
 
#ifndef __ASM__
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/register.h>
#include <arch/regdef.h>
#include <arch/asm.h>
 
#ifdef CONFIG_SMP
#include <arch/mm/cache.h>
#endif
 
typedef struct {
uint32_t mid; /**< Processor ID as read from
UPA_CONFIG. */
UPA_CONFIG/FIREPLANE_CONFIG. */
ver_reg_t ver;
uint32_t clock_frequency; /**< Processor frequency in Hz. */
uint64_t next_tick_cmpr; /**< Next clock interrupt should be
66,8 → 72,28
generated when the TICK register
matches this value. */
} cpu_arch_t;
 
 
/**
* Reads the module ID (agent ID/CPUID) of the current CPU.
*/
static inline uint32_t read_mid(void)
{
uint64_t icbus_config = asi_u64_read(ASI_ICBUS_CONFIG, 0);
icbus_config = icbus_config >> ICBUS_CONFIG_MID_SHIFT;
#if defined (US)
return icbus_config & 0x1f;
#elif defined (US3)
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIII_I)
return icbus_config & 0x1f;
else
return icbus_config & 0x3ff;
#endif
}
 
#endif
 
#endif
 
/** @}
*/
/branches/arm/kernel/arch/sparc64/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf64-sparc
BFD_ARCH = sparc
BFD = binary
44,82 → 40,58
 
LFLAGS += -no-check-sections -N
 
DEFS += -D__64_BITS__
BITS = 64
ENDIANESS = BE
 
## Own configuration directives
#
ifeq ($(PROCESSOR),us)
DEFS += -DUS
endif
 
## Compile with page hash table support.
#
ifeq ($(PROCESSOR),us3)
DEFS += -DUS3
endif
 
CONFIG_PAGE_HT = y
DEFS += -DCONFIG_PAGE_HT
ARCH_SOURCES = \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/panic.S \
arch/$(KARCH)/src/console.c \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/dummy.s \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/cache.S \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/sparc64.c \
arch/$(KARCH)/src/start.S \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/proc/thread.c \
arch/$(KARCH)/src/trap/mmu.S \
arch/$(KARCH)/src/trap/trap_table.S \
arch/$(KARCH)/src/trap/trap.c \
arch/$(KARCH)/src/trap/exception.c \
arch/$(KARCH)/src/trap/interrupt.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/drivers/tick.c \
arch/$(KARCH)/src/drivers/kbd.c \
arch/$(KARCH)/src/drivers/sgcn.c \
arch/$(KARCH)/src/drivers/pci.c \
arch/$(KARCH)/src/drivers/fhc.c
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## Compile with support for framebuffer.
#
 
CONFIG_FB = y
 
## Compile with support for Sun keyboard.
#
 
CONFIG_SUN_KBD = y
 
## Compile with support for OpenFirmware device tree.
#
 
CONFIG_OFW_TREE = y
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
ifeq ($(CONFIG_FB),y)
ARCH_SOURCES += \
arch/$(KARCH)/src/drivers/scr.c
endif
 
ARCH_SOURCES = \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/panic.S \
arch/$(ARCH)/src/console.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/cache.S \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/sparc64.c \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/proc/thread.c \
arch/$(ARCH)/src/trap/mmu.S \
arch/$(ARCH)/src/trap/trap_table.S \
arch/$(ARCH)/src/trap/trap.c \
arch/$(ARCH)/src/trap/exception.c \
arch/$(ARCH)/src/trap/interrupt.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/tick.c \
arch/$(ARCH)/src/drivers/kbd.c \
arch/$(ARCH)/src/drivers/scr.c \
arch/$(ARCH)/src/drivers/pci.c
 
ifeq ($(CONFIG_SMP),y)
ARCH_SOURCES += \
arch/$(ARCH)/src/smp/ipi.c \
arch/$(ARCH)/src/smp/smp.c
ARCH_SOURCES += \
arch/$(KARCH)/src/smp/ipi.c \
arch/$(KARCH)/src/smp/smp.c
endif
 
ifeq ($(CONFIG_TSB),y)
ARCH_SOURCES += \
arch/$(ARCH)/src/mm/tsb.c
ARCH_SOURCES += \
arch/$(KARCH)/src/mm/tsb.c
endif
 
ifdef CONFIG_Z8530
ARCH_SOURCES += \
arch/$(ARCH)/src/drivers/fhc.c
endif
/branches/arm/kernel/arch/sparc64/_link.ld.in
1,8 → 1,8
/** SPARC64 linker script
*
* It is ELF format, but its only section looks like this:
* kernel text
* kernel data
* kernel text
* kernel data
*
*/
 
11,7 → 11,7
ENTRY(kernel_image_start)
 
SECTIONS {
.image VMA: AT (LMA) {
.image VMA: AT (LMA) {
ktext_start = .;
*(K_TEXT_START)
*(.text);
21,23 → 21,23
*(K_DATA_START)
*(.rodata);
*(.rodata.*);
*(.data); /* initialized data */
*(.data); /* initialized data */
*(.sdata);
*(.sdata2);
*(.sbss);
. = ALIGN(8);
hardcoded_ktext_size = .;
QUAD(ktext_end - ktext_start);
QUAD(ktext_end - ktext_start);
hardcoded_kdata_size = .;
QUAD(kdata_end - kdata_start);
hardcoded_load_address = .;
QUAD(VMA);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
 
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
*(symtab.*); /* Symbol table, must be LAST symbol!*/
kdata_end = .;
}
44,5 → 44,5
/DISCARD/ : {
*(*);
}
 
}
/branches/arm/kernel/arch/mips32/include/console.h
File deleted
/branches/arm/kernel/arch/mips32/include/byteorder.h
File deleted
/branches/arm/kernel/arch/mips32/include/boot.h
File deleted
/branches/arm/kernel/arch/mips32/include/context_offset.h
76,26 → 76,17
#define EOFFSET_T5 0x30
#define EOFFSET_T6 0x34
#define EOFFSET_T7 0x38
#define EOFFSET_S0 0x3c
#define EOFFSET_S1 0x40
#define EOFFSET_S2 0x44
#define EOFFSET_S3 0x48
#define EOFFSET_S4 0x4c
#define EOFFSET_S5 0x50
#define EOFFSET_S6 0x54
#define EOFFSET_S7 0x58
#define EOFFSET_T8 0x5c
#define EOFFSET_T9 0x60
#define EOFFSET_GP 0x64
#define EOFFSET_SP 0x68
#define EOFFSET_S8 0x6c
#define EOFFSET_RA 0x70
#define EOFFSET_LO 0x74
#define EOFFSET_HI 0x78
#define EOFFSET_STATUS 0x7c
#define EOFFSET_EPC 0x80
#define EOFFSET_K1 0x84
#define REGISTER_SPACE 136
#define EOFFSET_T8 0x3c
#define EOFFSET_T9 0x40
#define EOFFSET_GP 0x44
#define EOFFSET_SP 0x48
#define EOFFSET_RA 0x4c
#define EOFFSET_LO 0x50
#define EOFFSET_HI 0x54
#define EOFFSET_STATUS 0x58
#define EOFFSET_EPC 0x5c
#define EOFFSET_K1 0x60
#define REGISTER_SPACE 104 /* respect stack alignment */
 
#ifdef __ASM__
 
114,10 → 105,10
sw $s8,OFFSET_S8(\ctx)
sw $gp,OFFSET_GP(\ctx)
 
#ifndef KERNEL
#ifndef KERNEL
sw $k1,OFFSET_TLS(\ctx)
 
# ifdef CONFIG_MIPS_FPU
#ifdef CONFIG_FPU
mfc1 $t0,$20
sw $t0, OFFSET_F20(\ctx)
 
150,7 → 141,7
mfc1 $t0,$30
sw $t0, OFFSET_F30(\ctx)
# endif /* CONFIG_MIPS_FPU */
#endif /* CONFIG_FPU */
#endif /* KERNEL */
 
sw $ra,OFFSET_PC(\ctx)
172,7 → 163,7
#ifndef KERNEL
lw $k1,OFFSET_TLS(\ctx)
 
# ifdef CONFIG_MIPS_FPU
#ifdef CONFIG_FPU
lw $t0, OFFSET_F20(\ctx)
mtc1 $t0,$20
 
205,9 → 196,9
 
lw $t0, OFFSET_F30(\ctx)
mtc1 $t0,$30
# endif /* CONFIG_MIPS_FPU */
#endif /* CONFIG_FPU */
#endif /* KERNEL */
 
lw $ra,OFFSET_PC(\ctx)
lw $sp,OFFSET_SP(\ctx)
.endm
/branches/arm/kernel/arch/mips32/include/elf.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
/** @addtogroup mips32
* @{
*/
/** @file
35,15 → 35,15
#ifndef KERN_mips32_ELF_H_
#define KERN_mips32_ELF_H_
 
#define ELF_MACHINE EM_MIPS
#define ELF_MACHINE EM_MIPS
 
#ifdef BIG_ENDIAN
# define ELF_DATA_ENCODING ELFDATA2MSB
#ifdef __BE__
#define ELF_DATA_ENCODING ELFDATA2MSB
#else
# define ELF_DATA_ENCODING ELFDATA2LSB
#define ELF_DATA_ENCODING ELFDATA2LSB
#endif
 
#define ELF_CLASS ELFCLASS32
#define ELF_CLASS ELFCLASS32
 
#endif
 
/branches/arm/kernel/arch/mips32/include/types.h
46,8 → 46,6
typedef unsigned long long uint64_t;
 
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
typedef uint32_t pfn_t;
57,10 → 55,11
typedef uint32_t unative_t;
typedef int32_t native_t;
 
typedef struct {
} fncptr_t;
 
#define PRIp "x" /**< Format for uintptr_t. */
#define PRIs "u" /**< Format for size_t. */
#define PRIc "u" /**< Format for count_t. */
#define PRIi "u" /**< Format for index_t. */
 
#define PRId8 "d" /**< Format for int8_t. */
#define PRId16 "d" /**< Format for int16_t. */
/branches/arm/kernel/arch/mips32/include/arch.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
/** @addtogroup mips32
* @{
*/
/** @file
35,6 → 35,29
#ifndef KERN_mips32_ARCH_H_
#define KERN_mips32_ARCH_H_
 
#define TASKMAP_MAX_RECORDS 32
#define CPUMAP_MAX_RECORDS 32
 
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
#include <typedefs.h>
 
extern size_t cpu_count;
 
typedef struct {
uintptr_t addr;
uint32_t size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} utask_t;
 
typedef struct {
uint32_t cpumap;
uint32_t cnt;
utask_t tasks[TASKMAP_MAX_RECORDS];
} bootinfo_t;
 
extern void arch_pre_main(void *entry, bootinfo_t *bootinfo);
 
#endif
 
/** @}
/branches/arm/kernel/arch/mips32/include/mm/page.h
112,21 → 112,21
 
/* Get PTE flags accessors for each level. */
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
get_pt_flags((pte_t *) (ptl0), (index_t) (i))
get_pt_flags((pte_t *) (ptl0), (size_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
get_pt_flags((pte_t *) (ptl3), (index_t) (i))
get_pt_flags((pte_t *) (ptl3), (size_t) (i))
 
/* Set PTE flags accessors for each level. */
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
 
/* Last-level info macros. */
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0)
140,7 → 140,7
#include <mm/mm.h>
#include <arch/exception.h>
 
static inline int get_pt_flags(pte_t *pt, index_t i)
static inline int get_pt_flags(pte_t *pt, size_t i)
{
pte_t *p = &pt[i];
153,7 → 153,7
(p->g << PAGE_GLOBAL_SHIFT));
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
{
pte_t *p = &pt[i];
/branches/arm/kernel/arch/mips32/include/mm/tlb.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
40,42 → 40,38
#include <arch/mm/asid.h>
#include <arch/exception.h>
 
#ifdef TLBCNT
# define TLB_ENTRY_COUNT TLBCNT
#else
# define TLB_ENTRY_COUNT 48
#endif
#define TLB_ENTRY_COUNT 48
 
#define TLB_WIRED 1
#define TLB_KSTACK_WIRED_INDEX 0
#define TLB_WIRED 1
#define TLB_KSTACK_WIRED_INDEX 0
 
#define TLB_PAGE_MASK_4K (0x000 << 13)
#define TLB_PAGE_MASK_16K (0x003 << 13)
#define TLB_PAGE_MASK_64K (0x00f << 13)
#define TLB_PAGE_MASK_256K (0x03f << 13)
#define TLB_PAGE_MASK_1M (0x0ff << 13)
#define TLB_PAGE_MASK_4M (0x3ff << 13)
#define TLB_PAGE_MASK_16M (0xfff << 13)
#define TLB_PAGE_MASK_4K (0x000 << 13)
#define TLB_PAGE_MASK_16K (0x003 << 13)
#define TLB_PAGE_MASK_64K (0x00f << 13)
#define TLB_PAGE_MASK_256K (0x03f << 13)
#define TLB_PAGE_MASK_1M (0x0ff << 13)
#define TLB_PAGE_MASK_4M (0x3ff << 13)
#define TLB_PAGE_MASK_16M (0xfff << 13)
 
#define PAGE_UNCACHED 2
#define PAGE_CACHEABLE_EXC_WRITE 5
#define PAGE_UNCACHED 2
#define PAGE_CACHEABLE_EXC_WRITE 5
 
typedef union {
struct {
#ifdef BIG_ENDIAN
unsigned : 2; /* zero */
unsigned pfn : 24; /* frame number */
unsigned c : 3; /* cache coherency attribute */
unsigned d : 1; /* dirty/write-protect bit */
unsigned v : 1; /* valid bit */
unsigned g : 1; /* global bit */
unsigned : 2; /* zero */
unsigned pfn : 24; /* frame number */
unsigned c : 3; /* cache coherency attribute */
unsigned d : 1; /* dirty/write-protect bit */
unsigned v : 1; /* valid bit */
unsigned g : 1; /* global bit */
#else
unsigned g : 1; /* global bit */
unsigned v : 1; /* valid bit */
unsigned d : 1; /* dirty/write-protect bit */
unsigned c : 3; /* cache coherency attribute */
unsigned pfn : 24; /* frame number */
unsigned : 2; /* zero */
unsigned g : 1; /* global bit */
unsigned v : 1; /* valid bit */
unsigned d : 1; /* dirty/write-protect bit */
unsigned c : 3; /* cache coherency attribute */
unsigned pfn : 24; /* frame number */
unsigned : 2; /* zero */
#endif
} __attribute__ ((packed));
uint32_t value;
163,7 → 159,7
asm volatile ("tlbwr\n\t");
}
 
#define tlb_invalidate(asid) tlb_invalidate_asid(asid)
#define tlb_invalidate(asid) tlb_invalidate_asid(asid)
 
extern void tlb_invalid(istate_t *istate);
extern void tlb_refill(istate_t *istate);
/branches/arm/kernel/arch/mips32/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
35,12 → 35,14
#ifndef KERN_mips32_FRAME_H_
#define KERN_mips32_FRAME_H_
 
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <typedefs.h>
 
extern void frame_arch_init(void);
extern void physmem_print(void);
 
/branches/arm/kernel/arch/mips32/include/mm/asid.h
37,7 → 37,7
 
#include <arch/types.h>
 
#define ASID_MAX_ARCH 255 /* 2^8 - 1 */
#define ASID_MAX_ARCH 255 /* 2^8 - 1 */
 
typedef uint8_t asid_t;
 
/branches/arm/kernel/arch/mips32/include/debugger.h
53,7 → 53,7
unative_t instruction; /**< Original instruction */
unative_t nextinstruction; /**< Original instruction following break */
int flags; /**< Flags regarding breakpoint */
count_t counter;
size_t counter;
void (*bkfunc)(void *b, istate_t *istate);
} bpinfo_t;
 
/branches/arm/kernel/arch/mips32/include/drivers/serial.h
File deleted
/branches/arm/kernel/arch/mips32/include/drivers/msim.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
/** @addtogroup mips32
* @{
*/
/** @file
36,16 → 36,10
#define KERN_mips32_MSIM_H_
 
/** Address of devices. */
#define MSIM_VIDEORAM 0x90000000
#define MSIM_KBD_ADDRESS 0x90000000
#define MSIM_KBD_IRQ 2
#define MSIM_VIDEORAM 0x90000000
#define MSIM_KBD_ADDRESS 0x90000000
#define MSIM_KBD_IRQ 2
 
#include <console/chardev.h>
 
void msim_console(devno_t devno);
void msim_kbd_release(void);
void msim_kbd_grab(void);
 
#endif
 
/** @}
/branches/arm/kernel/arch/mips32/include/asm.h
36,6 → 36,7
#define KERN_mips32_ASM_H_
 
#include <arch/types.h>
#include <typedefs.h>
#include <config.h>
 
 
55,7 → 56,11
{
uintptr_t v;
asm volatile ("and %0, $29, %1\n" : "=r" (v) : "r" (~(STACK_SIZE-1)));
asm volatile (
"and %0, $29, %1\n"
: "=r" (v)
: "r" (~(STACK_SIZE-1))
);
return v;
}
63,13 → 68,44
extern void cpu_halt(void);
extern void asm_delay_loop(uint32_t t);
extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg,
uintptr_t entry);
uintptr_t entry);
 
extern ipl_t interrupts_disable(void);
extern ipl_t interrupts_enable(void);
extern void interrupts_restore(ipl_t ipl);
extern ipl_t interrupts_read(void);
extern void asm_delay_loop(uint32_t t);
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
return *port;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
return *port;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
return *port;
}
 
#endif
 
/** @}
/branches/arm/kernel/arch/mips32/include/asm/boot.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
/** @addtogroup mips32
* @{
*/
/** @file
/branches/arm/kernel/arch/mips32/include/interrupt.h
38,9 → 38,11
#include <typedefs.h>
#include <arch/exception.h>
 
#define IVT_ITEMS 32
#define IVT_FIRST 0
#define IVT_ITEMS 32
#define IVT_FIRST 0
 
#define VECTOR_TLB_SHOOTDOWN_IPI EXC_Int
 
extern function virtual_timer_fnc;
extern uint32_t count_hi;
 
/branches/arm/kernel/arch/mips32/include/smp/order.h
File deleted
/branches/arm/kernel/arch/mips32/include/smp/dorder.h
0,0 → 1,34
/*
* Copyright (c) 2007 Martin Decky
* 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.
*/
 
#ifndef KERN_mips32_DORDER_H_
#define KERN_mips32_DORDER_H_
 
extern void ipi_broadcast_arch(int ipi);
 
#endif
/branches/arm/kernel/arch/mips32/include/atomic.h
35,14 → 35,14
#ifndef KERN_mips32_ATOMIC_H_
#define KERN_mips32_ATOMIC_H_
 
#define atomic_inc(x) ((void) atomic_add(x, 1))
#define atomic_dec(x) ((void) atomic_add(x, -1))
#define atomic_inc(x) ((void) atomic_add(x, 1))
#define atomic_dec(x) ((void) atomic_add(x, -1))
 
#define atomic_postinc(x) (atomic_add(x, 1) - 1)
#define atomic_postdec(x) (atomic_add(x, -1) + 1)
#define atomic_postinc(x) (atomic_add(x, 1) - 1)
#define atomic_postdec(x) (atomic_add(x, -1) + 1)
 
#define atomic_preinc(x) atomic_add(x, 1)
#define atomic_predec(x) atomic_add(x, -1)
#define atomic_preinc(x) atomic_add(x, 1)
#define atomic_predec(x) atomic_add(x, -1)
 
/* Atomic addition of immediate value.
*
54,19 → 54,37
static inline long atomic_add(atomic_t *val, int i)
{
long tmp, v;
 
asm volatile (
"1:\n"
" ll %0, %1\n"
" addu %0, %0, %3\n" /* same as addi, but never traps on overflow */
" move %2, %0\n"
" addu %0, %0, %3\n" /* same as addi, but never traps on overflow */
" move %2, %0\n"
" sc %0, %1\n"
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */
" nop\n"
: "=&r" (tmp), "+m" (val->count), "=&r" (v)
: "r" (i), "i" (0)
);
);
return v;
}
 
static inline uint32_t test_and_set(atomic_t *val) {
uint32_t tmp, v;
asm volatile (
"1:\n"
" ll %2, %1\n"
" bnez %2, 2f\n"
" li %0, %3\n"
" sc %0, %1\n"
" beqz %0, 1b\n"
"2:\n"
: "=&r" (tmp), "+m" (val->count), "=&r" (v)
: "i" (1)
);
return v;
}
 
/branches/arm/kernel/arch/mips32/include/cpu.h
42,7 → 42,7
uint32_t imp_num;
uint32_t rev_num;
} cpu_arch_t;
 
#endif
 
/** @}
/branches/arm/kernel/arch/mips32/include/exception.h
73,19 → 73,10
uint32_t t5;
uint32_t t6;
uint32_t t7;
uint32_t s0;
uint32_t s1;
uint32_t s2;
uint32_t s3;
uint32_t s4;
uint32_t s5;
uint32_t s6;
uint32_t s7;
uint32_t t8;
uint32_t t9;
uint32_t gp;
uint32_t sp;
uint32_t s8;
uint32_t ra;
uint32_t lo;
/branches/arm/kernel/arch/mips32/Makefile.inc
29,87 → 29,51
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_ARCH = mips
BFD = binary
TARGET = mipsel-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel
 
KERNEL_LOAD_ADDRESS = 0x80100000
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3
 
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss
BITS = 32
 
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS}
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## Accepted MACHINEs
#
 
ifeq ($(MACHINE),lgxemul)
BFD_NAME = elf32-tradlittlemips
BFD = binary
GCC_CFLAGS += -DFB_INVERT_ENDIAN -DARCH_HAS_FPU -mips3
ENDIANESS = LE
endif
ifeq ($(MACHINE),bgxemul)
BFD_NAME = elf32-bigmips
BFD = ecoff-bigmips
TARGET = mips-sgi-irix5
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin
GCC_CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -mips3
BFD_NAME = elf32-tradbigmips
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips
TARGET = mips-linux-gnu
ENDIANESS = BE
GCC_CFLAGS += -D__BE__
endif
ifeq ($(MACHINE),simics)
# SIMICS 4kc emulation is broken, although for instructions
# that do not bother us
BFD_NAME = elf32-tradlittlemips
BFD = elf32-tradlittlemips
GCC_CFLAGS += -mhard-float -mips3 -DTLBCNT=16
TLBCNT = 16
endif
ifeq ($(MACHINE),msim)
BFD_NAME = elf32-tradlittlemips
BFD = binary
GCC_CFLAGS += -mhard-float -mips3
ENDIANESS = LE
GCC_CFLAGS += -mhard-float
endif
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
 
ARCH_SOURCES = \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/panic.S \
arch/$(ARCH)/src/mips32.c \
arch/$(ARCH)/src/dummy.S \
arch/$(ARCH)/src/console.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/exception.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/cache.c \
arch/$(ARCH)/src/debugger.c \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/msim.c \
arch/$(ARCH)/src/drivers/serial.c \
arch/$(ARCH)/src/smp/order.c
arch/$(KARCH)/src/start.S \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/panic.S \
arch/$(KARCH)/src/mips32.c \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/exception.c \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/cache.c \
arch/$(KARCH)/src/debugger.c \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/smp/dorder.c \
arch/$(KARCH)/src/smp/smp.c
/branches/arm/kernel/arch/mips32/src/drivers/serial.c
File deleted
/branches/arm/kernel/arch/mips32/src/drivers/msim.c
File deleted
/branches/arm/kernel/arch/mips32/src/dummy.S
File deleted
/branches/arm/kernel/arch/mips32/src/console.c
File deleted
/branches/arm/kernel/arch/mips32/src/mm/tlb.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
40,12 → 40,12
#include <arch/cp0.h>
#include <panic.h>
#include <arch.h>
#include <symtab.h>
#include <synch/spinlock.h>
#include <synch/mutex.h>
#include <print.h>
#include <debug.h>
#include <align.h>
#include <interrupt.h>
#include <symtab.h>
 
static void tlb_refill_fail(istate_t *);
static void tlb_invalid_fail(istate_t *);
92,15 → 92,15
uintptr_t badvaddr;
pte_t *pte;
int pfrc;
 
badvaddr = cp0_badvaddr_read();
 
spinlock_lock(&AS->lock);
mutex_lock(&AS->lock);
asid = AS->asid;
spinlock_unlock(&AS->lock);
 
mutex_unlock(&AS->lock);
page_table_lock(AS, true);
 
pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc);
if (!pte) {
switch (pfrc) {
115,7 → 115,7
page_table_unlock(AS, true);
return;
default:
panic("unexpected pfrc (%d)\n", pfrc);
panic("Unexpected pfrc (%d).", pfrc);
}
}
 
199,7 → 199,7
page_table_unlock(AS, true);
return;
default:
panic("unexpected pfrc (%d)\n", pfrc);
panic("Unexpected pfrc (%d).", pfrc);
}
}
 
282,7 → 282,7
page_table_unlock(AS, true);
return;
default:
panic("unexpected pfrc (%d)\n", pfrc);
panic("Unexpected pfrc (%d).", pfrc);
}
}
 
320,19 → 320,14
 
void tlb_refill_fail(istate_t *istate)
{
char *symbol = "";
char *sym2 = "";
char *symbol, *sym2;
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
s = get_symtab_entry(istate->ra);
if (s)
sym2 = s;
 
fault_if_from_uspace(istate, "TLB Refill Exception on %p",
symbol = symtab_fmt_name_lookup(istate->epc);
sym2 = symtab_fmt_name_lookup(istate->ra);
fault_if_from_uspace(istate, "TLB Refill Exception on %p.",
cp0_badvaddr_read());
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(),
panic("%x: TLB Refill Exception at %x (%s<-%s).", cp0_badvaddr_read(),
istate->epc, symbol, sym2);
}
 
339,27 → 334,25
 
void tlb_invalid_fail(istate_t *istate)
{
char *symbol = "";
char *symbol;
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
fault_if_from_uspace(istate, "TLB Invalid Exception on %p",
symbol = symtab_fmt_name_lookup(istate->epc);
 
fault_if_from_uspace(istate, "TLB Invalid Exception on %p.",
cp0_badvaddr_read());
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(),
panic("%x: TLB Invalid Exception at %x (%s).", cp0_badvaddr_read(),
istate->epc, symbol);
}
 
void tlb_modified_fail(istate_t *istate)
{
char *symbol = "";
char *symbol;
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
fault_if_from_uspace(istate, "TLB Modified Exception on %p",
symbol = symtab_fmt_name_lookup(istate->epc);
 
fault_if_from_uspace(istate, "TLB Modified Exception on %p.",
cp0_badvaddr_read());
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(),
panic("%x: TLB Modified Exception at %x (%s).", cp0_badvaddr_read(),
istate->epc, symbol);
}
 
429,12 → 422,11
break;
case AS_PF_FAULT:
page_table_lock(AS, true);
printf("Page fault.\n");
*pfrc = AS_PF_FAULT;
return NULL;
break;
default:
panic("unexpected rc (%d)\n", rc);
panic("Unexpected rc (%d).", rc);
}
}
568,7 → 560,7
* @param page First page whose TLB entry is to be invalidated.
* @param cnt Number of entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
{
unsigned int i;
ipl_t ipl;
/branches/arm/kernel/arch/mips32/src/mm/frame.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
40,22 → 40,22
#include <mm/asid.h>
#include <config.h>
#include <arch/drivers/msim.h>
#include <arch/drivers/serial.h>
#include <print.h>
 
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K
#define ZERO_FRAMES 2048
#define ZERO_PAGE_WIDTH 18 /* 256K */
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH)
#define ZERO_PAGE_ASID ASID_INVALID
#define ZERO_PAGE_TLBI 0
#define ZERO_PAGE_ADDR 0
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1)
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET])
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K
#define ZERO_FRAMES 2048
#define ZERO_PAGE_WIDTH 18 /* 256K */
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH)
#define ZERO_PAGE_ASID ASID_INVALID
#define ZERO_PAGE_TLBI 0
#define ZERO_PAGE_ADDR 0
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1)
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET])
 
#define ZERO_PAGE_VALUE_KSEG1(frame) (((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET])
#define ZERO_PAGE_VALUE_KSEG1(frame) \
(((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET])
 
#define MAX_REGIONS 32
#define MAX_REGIONS 32
 
typedef struct {
pfn_t start;
62,10 → 62,9
pfn_t count;
} phys_region_t;
 
static count_t phys_regions_count = 0;
static size_t phys_regions_count = 0;
static phys_region_t phys_regions[MAX_REGIONS];
 
 
/** Check whether frame is available
*
* Returns true if given frame is generally available for use.
75,7 → 74,7
*/
static bool frame_available(pfn_t frame)
{
#if MACHINE == msim
#ifdef MACHINE_msim
/* MSIM device (dprinter) */
if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH))
return false;
84,14 → 83,8
if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH))
return false;
#endif
 
#if MACHINE == simics
/* Simics device (serial line) */
if (frame == (KA2PA(SERIAL_ADDRESS) >> ZERO_PAGE_WIDTH))
return false;
#endif
 
#if (MACHINE == lgxemul) || (MACHINE == bgxemul)
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)
/* gxemul devices */
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
0x10000000, MB2SIZE(256)))
126,7 → 119,7
/* Init tasks */
bool safe = true;
count_t i;
size_t i;
for (i = 0; i < init.cnt; i++)
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
KA2PA(init.tasks[i].addr), init.tasks[i].size)) {
181,7 → 174,7
cp0_entry_lo1_write(0);
cp0_entry_hi_write(0);
 
count_t i;
size_t i;
for (i = 0; i < TLB_ENTRY_COUNT; i++) {
cp0_index_write(i);
tlbwi();
218,7 → 211,7
ZERO_PAGE_VALUE = 0xdeadbeef;
if (ZERO_PAGE_VALUE != 0xdeadbeef)
avail = false;
#if (MACHINE == lgxemul) || (MACHINE == bgxemul)
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)
else {
ZERO_PAGE_VALUE_KSEG1(frame) = 0xaabbccdd;
if (ZERO_PAGE_VALUE_KSEG1(frame) != 0xaabbccdd)
258,7 → 251,7
printf("Base Size\n");
printf("---------- ----------\n");
count_t i;
size_t i;
for (i = 0; i < phys_regions_count; i++) {
printf("%#010x %10u\n",
PFN2ADDR(phys_regions[i].start), PFN2ADDR(phys_regions[i].count));
/branches/arm/kernel/arch/mips32/src/mm/page.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
35,6 → 35,7
#include <arch/mm/page.h>
#include <genarch/mm/page_pt.h>
#include <mm/page.h>
#include <mm/frame.h>
 
void page_arch_init(void)
{
/branches/arm/kernel/arch/mips32/src/mips32.c
33,20 → 33,17
*/
 
#include <arch.h>
#include <arch/boot.h>
#include <arch/cp0.h>
#include <arch/exception.h>
#include <mm/as.h>
 
#include <userspace.h>
#include <arch/console.h>
#include <memstr.h>
#include <proc/thread.h>
#include <proc/uarg.h>
#include <print.h>
#include <console/console.h>
#include <syscall/syscall.h>
#include <sysinfo/sysinfo.h>
 
#include <arch/interrupt.h>
#include <console/chardev.h>
#include <arch/barrier.h>
53,39 → 50,51
#include <arch/debugger.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <genarch/drivers/dsrln/dsrlnin.h>
#include <genarch/drivers/dsrln/dsrlnout.h>
#include <genarch/srln/srln.h>
#include <macros.h>
#include <ddi/device.h>
 
#include <config.h>
#include <string.h>
#include <arch/drivers/msim.h>
#include <arch/asm/regname.h>
 
/* Size of the code jumping to the exception handler code
* - J+NOP
/* Size of the code jumping to the exception handler code
* - J+NOP
*/
#define EXCEPTION_JUMP_SIZE 8
#define EXCEPTION_JUMP_SIZE 8
 
#define TLB_EXC ((char *) 0x80000000)
#define NORM_EXC ((char *) 0x80000180)
#define CACHE_EXC ((char *) 0x80000100)
#define TLB_EXC ((char *) 0x80000000)
#define NORM_EXC ((char *) 0x80000180)
#define CACHE_EXC ((char *) 0x80000100)
 
 
/* Why the linker moves the variable 64K away in assembler
* when not in .text section ????????
* when not in .text section?
*/
 
/* Stack pointer saved when entering user mode */
uintptr_t supervisor_sp __attribute__ ((section (".text")));
/* Stack pointer saved when entering user mode */
/* TODO: How do we do it on SMP system???? */
bootinfo_t bootinfo __attribute__ ((section (".text")));
 
void arch_pre_main(void)
size_t cpu_count = 0;
 
/** Performs mips32-specific initialization before main_bsp() is called. */
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo)
{
/* Setup usermode */
init.cnt = bootinfo.cnt;
init.cnt = bootinfo->cnt;
uint32_t i;
size_t i;
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) {
init.tasks[i].addr = bootinfo->tasks[i].addr;
init.tasks[i].size = bootinfo->tasks[i].size;
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
bootinfo->tasks[i].name);
}
for (i = 0; i < bootinfo.cnt; i++) {
init.tasks[i].addr = bootinfo.tasks[i].addr;
init.tasks[i].size = bootinfo.tasks[i].size;
for (i = 0; i < CPUMAP_MAX_RECORDS; i++) {
if ((bootinfo->cpumap & (1 << i)) != 0)
cpu_count++;
}
}
 
111,12 → 120,12
*/
cp0_status_write(cp0_status_read() &
~(cp0_status_bev_bootstrap_bit | cp0_status_erl_error_bit));
 
/*
* Mask all interrupts
/*
* Mask all interrupts
*/
cp0_mask_all_int();
debugger_init();
}
 
123,12 → 132,23
void arch_post_mm_init(void)
{
interrupt_init();
console_init(device_assign_devno());
#ifdef CONFIG_FB
/* GXemul framebuffer */
fb_init(0x12000000, 640, 480, 1920, VISUAL_RGB_8_8_8);
#endif
sysinfo_set_item_val("machine." STRING(MACHINE), NULL, 1);
fb_properties_t gxemul_prop = {
.addr = 0x12000000,
.offset = 0,
.x = 640,
.y = 480,
.scan = 1920,
.visual = VISUAL_BGR_8_8_8,
};
fb_init(&gxemul_prop);
#else
#ifdef CONFIG_MIPS_PRN
dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS);
#endif /* CONFIG_MIPS_PRN */
#endif /* CONFIG_FB */
}
 
void arch_post_cpu_init(void)
141,8 → 161,37
 
void arch_post_smp_init(void)
{
#ifdef CONFIG_MIPS_KBD
/*
* Initialize the msim/GXemul keyboard port. Then initialize the serial line
* module and connect it to the msim/GXemul keyboard. Enable keyboard interrupts.
*/
dsrlnin_instance_t *dsrlnin_instance
= dsrlnin_init((dsrlnin_t *) MSIM_KBD_ADDRESS, MSIM_KBD_IRQ);
if (dsrlnin_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
dsrlnin_wire(dsrlnin_instance, srln);
cp0_unmask_int(MSIM_KBD_IRQ);
}
}
/*
* 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, MSIM_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS);
#endif
}
 
void calibrate_delay_loop(void)
{
}
 
void userspace(uspace_arg_t *kernel_uarg)
{
/* EXL = 1, UM = 1, IE = 1 */
153,8 → 202,7
(uintptr_t) kernel_uarg->uspace_uarg,
(uintptr_t) kernel_uarg->uspace_entry);
while (1)
;
while (1);
}
 
/** Perform mips32 specific tasks needed before the new task is run. */
186,10 → 234,36
void arch_reboot(void)
{
___halt();
while (1)
;
while (1);
}
 
/** 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;
}
 
void arch_grab_console(void)
{
#ifdef CONFIG_FB
fb_redraw();
#endif
}
 
/** Return console to userspace
*
*/
void arch_release_console(void)
{
}
 
/** @}
*/
/branches/arm/kernel/arch/mips32/src/asm.S
27,17 → 27,17
#
 
#include <arch/asm/regname.h>
 
.text
 
.macro cp0_read reg
mfc0 $2,\reg
mfc0 $2, \reg
j $31
nop
.endm
 
.macro cp0_write reg
mtc0 $4,\reg
mtc0 $4, \reg
j $31
nop
.endm
46,6 → 46,11
.set noreorder
.set nomacro
 
.global asm_delay_loop
asm_delay_loop:
j $31
nop
 
.global cpu_halt
cpu_halt:
j cpu_halt
58,6 → 63,12
nop
 
 
.global memsetw
memsetw:
j _memsetw
nop
 
 
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
66,235 → 77,238
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
addiu $v0,$a1,3
li $v1,-4 # 0xfffffffffffffffc
and $v0,$v0,$v1
beq $a1,$v0,3f
move $t0,$a0
move $t2,$a0 # save dst
move $t2, $a0 # save dst
addiu $v0, $a1, 3
li $v1, -4 # 0xfffffffffffffffc
and $v0, $v0, $v1
beq $a1, $v0, 3f
move $t0, $a0
0:
beq $a2, $zero, 2f
move $a3, $zero
1:
addu $v0, $a1, $a3
lbu $a0, 0($v0)
addu $v1, $t0, $a3
addiu $a3, $a3, 1
bne $a3, $a2, 1b
sb $a0, 0($v1)
2:
jr $ra
move $v0, $t2
3:
addiu $v0, $a0, 3
and $v0, $v0, $v1
bne $a0, $v0, 0b
srl $t1, $a2, 2
beq $t1, $zero, 5f
move $a3, $zero
move $a3, $zero
move $a0, $zero
4:
addu $v0, $a1, $a0
lw $v1, 0($v0)
addiu $a3, $a3, 1
addu $v0, $t0, $a0
sw $v1, 0($v0)
bne $a3, $t1, 4b
addiu $a0, $a0, 4
5:
andi $a2, $a2, 0x3
beq $a2, $zero, 2b
nop
sll $v0, $a3, 2
addu $t1, $v0, $t0
move $a3, $zero
addu $t0, $v0, $a1
6:
addu $v0, $t0, $a3
lbu $a0, 0($v0)
addu $v1, $t1, $a3
addiu $a3, $a3, 1
bne $a3, $a2, 6b
sb $a0, 0($v1)
jr $ra
move $v0, $t2
 
0:
beq $a2,$zero,2f
move $a3,$zero
 
1:
addu $v0,$a1,$a3
lbu $a0,0($v0)
addu $v1,$t0,$a3
addiu $a3,$a3,1
bne $a3,$a2,1b
sb $a0,0($v1)
 
2:
jr $ra
move $v0,$t2
 
3:
addiu $v0,$a0,3
and $v0,$v0,$v1
bne $a0,$v0,0b
srl $t1,$a2,2
 
beq $t1,$zero,5f
move $a3,$zero
 
move $a3,$zero
move $a0,$zero
4:
addu $v0,$a1,$a0
lw $v1,0($v0)
addiu $a3,$a3,1
addu $v0,$t0,$a0
sw $v1,0($v0)
bne $a3,$t1,4b
addiu $a0,$a0,4
 
5:
andi $a2,$a2,0x3
beq $a2,$zero,2b
nop
 
sll $v0,$a3,2
addu $t1,$v0,$t0
move $a3,$zero
addu $t0,$v0,$a1
6:
addu $v0,$t0,$a3
lbu $a0,0($v0)
addu $v1,$t1,$a3
addiu $a3,$a3,1
bne $a3,$a2,6b
sb $a0,0($v1)
 
jr $ra
move $v0,$t2
 
memcpy_from_uspace_failover_address:
memcpy_to_uspace_failover_address:
jr $ra
move $v0, $zero
jr $ra
move $v0, $zero
 
 
 
.macro fpu_gp_save reg ctx
mfc1 $t0,$\reg
sw $t0, \reg*4(\ctx)
mfc1 $t0, $\reg
sw $t0, \reg * 4(\ctx)
.endm
 
.macro fpu_gp_restore reg ctx
lw $t0, \reg*4(\ctx)
mtc1 $t0,$\reg
lw $t0, \reg * 4(\ctx)
mtc1 $t0, $\reg
.endm
 
.macro fpu_ct_save reg ctx
cfc1 $t0,$1
sw $t0, (\reg+32)*4(\ctx)
cfc1 $t0, $1
sw $t0, (\reg + 32) * 4(\ctx)
.endm
 
.macro fpu_ct_restore reg ctx
lw $t0, (\reg+32)*4(\ctx)
ctc1 $t0,$\reg
lw $t0, (\reg + 32) * 4(\ctx)
ctc1 $t0, $\reg
.endm
 
 
.global fpu_context_save
fpu_context_save:
#ifdef ARCH_HAS_FPU
fpu_gp_save 0,$a0
fpu_gp_save 1,$a0
fpu_gp_save 2,$a0
fpu_gp_save 3,$a0
fpu_gp_save 4,$a0
fpu_gp_save 5,$a0
fpu_gp_save 6,$a0
fpu_gp_save 7,$a0
fpu_gp_save 8,$a0
fpu_gp_save 9,$a0
fpu_gp_save 10,$a0
fpu_gp_save 11,$a0
fpu_gp_save 12,$a0
fpu_gp_save 13,$a0
fpu_gp_save 14,$a0
fpu_gp_save 15,$a0
fpu_gp_save 16,$a0
fpu_gp_save 17,$a0
fpu_gp_save 18,$a0
fpu_gp_save 19,$a0
fpu_gp_save 20,$a0
fpu_gp_save 21,$a0
fpu_gp_save 22,$a0
fpu_gp_save 23,$a0
fpu_gp_save 24,$a0
fpu_gp_save 25,$a0
fpu_gp_save 26,$a0
fpu_gp_save 27,$a0
fpu_gp_save 28,$a0
fpu_gp_save 29,$a0
fpu_gp_save 30,$a0
fpu_gp_save 31,$a0
 
fpu_ct_save 1,$a0
fpu_ct_save 2,$a0
fpu_ct_save 3,$a0
fpu_ct_save 4,$a0
fpu_ct_save 5,$a0
fpu_ct_save 6,$a0
fpu_ct_save 7,$a0
fpu_ct_save 8,$a0
fpu_ct_save 9,$a0
fpu_ct_save 10,$a0
fpu_ct_save 11,$a0
fpu_ct_save 12,$a0
fpu_ct_save 13,$a0
fpu_ct_save 14,$a0
fpu_ct_save 15,$a0
fpu_ct_save 16,$a0
fpu_ct_save 17,$a0
fpu_ct_save 18,$a0
fpu_ct_save 19,$a0
fpu_ct_save 20,$a0
fpu_ct_save 21,$a0
fpu_ct_save 22,$a0
fpu_ct_save 23,$a0
fpu_ct_save 24,$a0
fpu_ct_save 25,$a0
fpu_ct_save 26,$a0
fpu_ct_save 27,$a0
fpu_ct_save 28,$a0
fpu_ct_save 29,$a0
fpu_ct_save 30,$a0
fpu_ct_save 31,$a0
#endif
#ifdef CONFIG_FPU
fpu_gp_save 0, $a0
fpu_gp_save 1, $a0
fpu_gp_save 2, $a0
fpu_gp_save 3, $a0
fpu_gp_save 4, $a0
fpu_gp_save 5, $a0
fpu_gp_save 6, $a0
fpu_gp_save 7, $a0
fpu_gp_save 8, $a0
fpu_gp_save 9, $a0
fpu_gp_save 10, $a0
fpu_gp_save 11, $a0
fpu_gp_save 12, $a0
fpu_gp_save 13, $a0
fpu_gp_save 14, $a0
fpu_gp_save 15, $a0
fpu_gp_save 16, $a0
fpu_gp_save 17, $a0
fpu_gp_save 18, $a0
fpu_gp_save 19, $a0
fpu_gp_save 20, $a0
fpu_gp_save 21, $a0
fpu_gp_save 22, $a0
fpu_gp_save 23, $a0
fpu_gp_save 24, $a0
fpu_gp_save 25, $a0
fpu_gp_save 26, $a0
fpu_gp_save 27, $a0
fpu_gp_save 28, $a0
fpu_gp_save 29, $a0
fpu_gp_save 30, $a0
fpu_gp_save 31, $a0
fpu_ct_save 1, $a0
fpu_ct_save 2, $a0
fpu_ct_save 3, $a0
fpu_ct_save 4, $a0
fpu_ct_save 5, $a0
fpu_ct_save 6, $a0
fpu_ct_save 7, $a0
fpu_ct_save 8, $a0
fpu_ct_save 9, $a0
fpu_ct_save 10, $a0
fpu_ct_save 11, $a0
fpu_ct_save 12, $a0
fpu_ct_save 13, $a0
fpu_ct_save 14, $a0
fpu_ct_save 15, $a0
fpu_ct_save 16, $a0
fpu_ct_save 17, $a0
fpu_ct_save 18, $a0
fpu_ct_save 19, $a0
fpu_ct_save 20, $a0
fpu_ct_save 21, $a0
fpu_ct_save 22, $a0
fpu_ct_save 23, $a0
fpu_ct_save 24, $a0
fpu_ct_save 25, $a0
fpu_ct_save 26, $a0
fpu_ct_save 27, $a0
fpu_ct_save 28, $a0
fpu_ct_save 29, $a0
fpu_ct_save 30, $a0
fpu_ct_save 31, $a0
#endif
j $ra
nop
 
.global fpu_context_restore
fpu_context_restore:
#ifdef ARCH_HAS_FPU
fpu_gp_restore 0,$a0
fpu_gp_restore 1,$a0
fpu_gp_restore 2,$a0
fpu_gp_restore 3,$a0
fpu_gp_restore 4,$a0
fpu_gp_restore 5,$a0
fpu_gp_restore 6,$a0
fpu_gp_restore 7,$a0
fpu_gp_restore 8,$a0
fpu_gp_restore 9,$a0
fpu_gp_restore 10,$a0
fpu_gp_restore 11,$a0
fpu_gp_restore 12,$a0
fpu_gp_restore 13,$a0
fpu_gp_restore 14,$a0
fpu_gp_restore 15,$a0
fpu_gp_restore 16,$a0
fpu_gp_restore 17,$a0
fpu_gp_restore 18,$a0
fpu_gp_restore 19,$a0
fpu_gp_restore 20,$a0
fpu_gp_restore 21,$a0
fpu_gp_restore 22,$a0
fpu_gp_restore 23,$a0
fpu_gp_restore 24,$a0
fpu_gp_restore 25,$a0
fpu_gp_restore 26,$a0
fpu_gp_restore 27,$a0
fpu_gp_restore 28,$a0
fpu_gp_restore 29,$a0
fpu_gp_restore 30,$a0
fpu_gp_restore 31,$a0
 
fpu_ct_restore 1,$a0
fpu_ct_restore 2,$a0
fpu_ct_restore 3,$a0
fpu_ct_restore 4,$a0
fpu_ct_restore 5,$a0
fpu_ct_restore 6,$a0
fpu_ct_restore 7,$a0
fpu_ct_restore 8,$a0
fpu_ct_restore 9,$a0
fpu_ct_restore 10,$a0
fpu_ct_restore 11,$a0
fpu_ct_restore 12,$a0
fpu_ct_restore 13,$a0
fpu_ct_restore 14,$a0
fpu_ct_restore 15,$a0
fpu_ct_restore 16,$a0
fpu_ct_restore 17,$a0
fpu_ct_restore 18,$a0
fpu_ct_restore 19,$a0
fpu_ct_restore 20,$a0
fpu_ct_restore 21,$a0
fpu_ct_restore 22,$a0
fpu_ct_restore 23,$a0
fpu_ct_restore 24,$a0
fpu_ct_restore 25,$a0
fpu_ct_restore 26,$a0
fpu_ct_restore 27,$a0
fpu_ct_restore 28,$a0
fpu_ct_restore 29,$a0
fpu_ct_restore 30,$a0
fpu_ct_restore 31,$a0
#endif
#ifdef CONFIG_FPU
fpu_gp_restore 0, $a0
fpu_gp_restore 1, $a0
fpu_gp_restore 2, $a0
fpu_gp_restore 3, $a0
fpu_gp_restore 4, $a0
fpu_gp_restore 5, $a0
fpu_gp_restore 6, $a0
fpu_gp_restore 7, $a0
fpu_gp_restore 8, $a0
fpu_gp_restore 9, $a0
fpu_gp_restore 10, $a0
fpu_gp_restore 11, $a0
fpu_gp_restore 12, $a0
fpu_gp_restore 13, $a0
fpu_gp_restore 14, $a0
fpu_gp_restore 15, $a0
fpu_gp_restore 16, $a0
fpu_gp_restore 17, $a0
fpu_gp_restore 18, $a0
fpu_gp_restore 19, $a0
fpu_gp_restore 20, $a0
fpu_gp_restore 21, $a0
fpu_gp_restore 22, $a0
fpu_gp_restore 23, $a0
fpu_gp_restore 24, $a0
fpu_gp_restore 25, $a0
fpu_gp_restore 26, $a0
fpu_gp_restore 27, $a0
fpu_gp_restore 28, $a0
fpu_gp_restore 29, $a0
fpu_gp_restore 30, $a0
fpu_gp_restore 31, $a0
fpu_ct_restore 1, $a0
fpu_ct_restore 2, $a0
fpu_ct_restore 3, $a0
fpu_ct_restore 4, $a0
fpu_ct_restore 5, $a0
fpu_ct_restore 6, $a0
fpu_ct_restore 7, $a0
fpu_ct_restore 8, $a0
fpu_ct_restore 9, $a0
fpu_ct_restore 10, $a0
fpu_ct_restore 11, $a0
fpu_ct_restore 12, $a0
fpu_ct_restore 13, $a0
fpu_ct_restore 14, $a0
fpu_ct_restore 15, $a0
fpu_ct_restore 16, $a0
fpu_ct_restore 17, $a0
fpu_ct_restore 18, $a0
fpu_ct_restore 19, $a0
fpu_ct_restore 20, $a0
fpu_ct_restore 21, $a0
fpu_ct_restore 22, $a0
fpu_ct_restore 23, $a0
fpu_ct_restore 24, $a0
fpu_ct_restore 25, $a0
fpu_ct_restore 26, $a0
fpu_ct_restore 27, $a0
fpu_ct_restore 28, $a0
fpu_ct_restore 29, $a0
fpu_ct_restore 30, $a0
fpu_ct_restore 31, $a0
#endif
j $ra
nop
/branches/arm/kernel/arch/mips32/src/exception.c
41,13 → 41,12
#include <arch.h>
#include <debug.h>
#include <proc/thread.h>
#include <symtab.h>
#include <print.h>
#include <interrupt.h>
#include <func.h>
#include <console/kconsole.h>
#include <ddi/irq.h>
#include <arch/debugger.h>
#include <symtab.h>
 
static char * exctable[] = {
"Interrupt",
74,25 → 73,21
 
static void print_regdump(istate_t *istate)
{
char *pcsymbol = "";
char *rasymbol = "";
char *pcsymbol, *rasymbol;
 
char *s = get_symtab_entry(istate->epc);
if (s)
pcsymbol = s;
s = get_symtab_entry(istate->ra);
if (s)
rasymbol = s;
printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol, istate->ra, rasymbol, istate->sp);
pcsymbol = symtab_fmt_name_lookup(istate->epc);
rasymbol = symtab_fmt_name_lookup(istate->ra);
 
printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol,
istate->ra, rasymbol, istate->sp);
}
 
static void unhandled_exception(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "unhandled exception %s", exctable[n]);
fault_if_from_uspace(istate, "Unhandled exception %s.", exctable[n]);
print_regdump(istate);
panic("unhandled exception %s\n", exctable[n]);
panic("Unhandled exception %s.", exctable[n]);
}
 
static void reserved_instr_exception(int n, istate_t *istate)
133,8 → 128,8
if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id)
scheduler_fpu_lazy_request();
else {
fault_if_from_uspace(istate, "unhandled Coprocessor Unusable Exception");
panic("unhandled Coprocessor Unusable Exception\n");
fault_if_from_uspace(istate, "Unhandled Coprocessor Unusable Exception.");
panic("Unhandled Coprocessor Unusable Exception.");
}
}
#endif
145,7 → 140,7
int i;
/* decode interrupt number and process the interrupt */
cause = (cp0_cause_read() >> 8) &0xff;
cause = (cp0_cause_read() >> 8) & 0xff;
for (i = 0; i < 8; i++) {
if (cause & (1 << i)) {
154,7 → 149,7
/*
* The IRQ handler was found.
*/
irq->handler(irq, irq->arg);
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/*
161,7 → 156,8
* Spurious interrupt.
*/
#ifdef CONFIG_DEBUG
printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, i);
printf("cpu%u: spurious interrupt (inum=%d)\n",
CPU->id, i);
#endif
}
}
171,7 → 167,7
/** Handle syscall userspace call */
static void syscall_exception(int n, istate_t *istate)
{
panic("Syscall is handled through shortcut");
panic("Syscall is handled through shortcut.");
}
 
void exception_init(void)
/branches/arm/kernel/arch/mips32/src/debugger.c
37,16 → 37,18
#include <memstr.h>
#include <console/kconsole.h>
#include <console/cmd.h>
#include <symtab.h>
#include <print.h>
#include <panic.h>
#include <arch.h>
#include <arch/cp0.h>
#include <func.h>
#include <symtab.h>
 
bpinfo_t breakpoints[BKPOINTS_MAX];
SPINLOCK_INITIALIZE(bkpoint_lock);
 
#ifdef CONFIG_KCONSOLE
 
static int cmd_print_breakpoints(cmd_arg_t *argv);
static cmd_info_t bkpts_info = {
.name = "bkpts",
123,10 → 125,12
{0, 0} /* EndOfTable */
};
 
 
/** Test, if the given instruction is a jump or branch instruction
*
* @param instr Instruction code
* @return true - it is jump instruction, false otherwise
*
*/
static bool is_jump(unative_t instr)
{
158,7 → 162,7
for (i = 0; i < BKPOINTS_MAX; i++) {
if (breakpoints[i].address == (uintptr_t)argv->intval) {
printf("Duplicate breakpoint %d.\n", i);
spinlock_unlock(&bkpoints_lock);
spinlock_unlock(&bkpoint_lock);
return 0;
} else if (breakpoints[i].address == (uintptr_t)argv->intval +
sizeof(unative_t) || breakpoints[i].address ==
165,10 → 169,10
(uintptr_t)argv->intval - sizeof(unative_t)) {
printf("Adjacent breakpoints not supported, conflict "
"with %d.\n", i);
spinlock_unlock(&bkpoints_lock);
spinlock_unlock(&bkpoint_lock);
return 0;
}
}
 
for (i = 0; i < BKPOINTS_MAX; i++)
255,8 → 259,9
for (i = 0; i < BKPOINTS_MAX; i++)
if (breakpoints[i].address) {
symbol = get_symtab_entry(breakpoints[i].address);
symbol = symtab_fmt_name_lookup(
breakpoints[i].address);
 
printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i,
breakpoints[i].counter, breakpoints[i].address,
((breakpoints[i].flags & BKPOINT_INPROG) ? "true" :
267,6 → 272,8
return 1;
}
 
#endif
 
/** Initialize debugger */
void debugger_init()
{
274,22 → 281,24
 
for (i = 0; i < BKPOINTS_MAX; i++)
breakpoints[i].address = NULL;
 
#ifdef CONFIG_KCONSOLE
cmd_initialize(&bkpts_info);
if (!cmd_register(&bkpts_info))
panic("could not register command %s\n", bkpts_info.name);
printf("Cannot register command %s\n", bkpts_info.name);
 
cmd_initialize(&delbkpt_info);
if (!cmd_register(&delbkpt_info))
panic("could not register command %s\n", delbkpt_info.name);
printf("Cannot register command %s\n", delbkpt_info.name);
 
cmd_initialize(&addbkpt_info);
if (!cmd_register(&addbkpt_info))
panic("could not register command %s\n", addbkpt_info.name);
printf("Cannot register command %s\n", addbkpt_info.name);
 
cmd_initialize(&addbkpte_info);
if (!cmd_register(&addbkpte_info))
panic("could not register command %s\n", addbkpte_info.name);
printf("Cannot register command %s\n", addbkpte_info.name);
#endif
}
 
/** Handle breakpoint
308,7 → 317,7
 
/* test branch delay slot */
if (cp0_cause_read() & 0x80000000)
panic("Breakpoint in branch delay slot not supported.\n");
panic("Breakpoint in branch delay slot not supported.");
 
spinlock_lock(&bkpoint_lock);
for (i = 0; i < BKPOINTS_MAX; i++) {
340,9 → 349,10
if (cur->flags & BKPOINT_INPROG)
printf("Warning: breakpoint recursion\n");
if (!(cur->flags & BKPOINT_FUNCCALL))
if (!(cur->flags & BKPOINT_FUNCCALL)) {
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
get_symtab_entry(istate->epc));
symtab_fmt_name_lookup(istate->epc));
}
 
/* Return first instruction back */
((uint32_t *)cur->address)[0] = cur->instruction;
355,8 → 365,9
}
cur->flags |= BKPOINT_INPROG;
} else {
printf("***Breakpoint %p in %s.\n", fireaddr,
get_symtab_entry(fireaddr));
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
symtab_fmt_name_lookup(fireaddr));
 
/* Move on to next instruction */
istate->epc += 4;
}
367,19 → 378,20
if (cur->bkfunc)
cur->bkfunc(cur, istate);
} else {
printf("***Type 'exit' to exit kconsole.\n");
#ifdef CONFIG_KCONSOLE
/* This disables all other processors - we are not SMP,
* actually this gets us to cpu_halt, if scheduler() is run
* - we generally do not want scheduler to be run from debug,
* so this is a good idea
*/
atomic_set(&haltstate,1);
atomic_set(&haltstate, 1);
spinlock_unlock(&bkpoint_lock);
 
kconsole("debug");
 
kconsole("debug", "Debug console ready.\n", false);
spinlock_lock(&bkpoint_lock);
atomic_set(&haltstate,0);
atomic_set(&haltstate, 0);
#endif
}
if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) {
/* Remove one-shot breakpoint */
/branches/arm/kernel/arch/mips32/src/interrupt.c
41,8 → 41,9
#include <ipc/sysipc.h>
#include <ddi/device.h>
 
#define IRQ_COUNT 8
#define TIMER_IRQ 7
#define IRQ_COUNT 8
#define TIMER_IRQ 7
#define DORDER_IRQ 5
 
function virtual_timer_fnc = NULL;
static irq_t timer_irq;
100,12 → 101,12
cp0_compare_write(nextcount);
}
 
static irq_ownership_t timer_claim(void)
static irq_ownership_t timer_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
static void timer_irq_handler(irq_t *irq, void *arg, ...)
static void timer_irq_handler(irq_t *irq)
{
unsigned long drift;
/branches/arm/kernel/arch/mips32/src/start.S
31,7 → 31,7
#include <arch/asm/boot.h>
#include <arch/context_offset.h>
#include <arch/stack.h>
 
.text
 
.set noat
75,18 → 75,6
mfhi $at
sw $at, EOFFSET_HI(\r)
#ifdef CONFIG_DEBUG_ALLREGS
sw $s0, EOFFSET_S0(\r)
sw $s1, EOFFSET_S1(\r)
sw $s2, EOFFSET_S2(\r)
sw $s3, EOFFSET_S3(\r)
sw $s4, EOFFSET_S4(\r)
sw $s5, EOFFSET_S5(\r)
sw $s6, EOFFSET_S6(\r)
sw $s7, EOFFSET_S7(\r)
sw $s8, EOFFSET_S8(\r)
#endif
sw $gp, EOFFSET_GP(\r)
sw $ra, EOFFSET_RA(\r)
sw $k1, EOFFSET_K1(\r)
132,17 → 120,6
lw $t8, EOFFSET_T8(\r)
lw $t9, EOFFSET_T9(\r)
#ifdef CONFIG_DEBUG_ALLREGS
lw $s0, EOFFSET_S0(\r)
lw $s1, EOFFSET_S1(\r)
lw $s2, EOFFSET_S2(\r)
lw $s3, EOFFSET_S3(\r)
lw $s4, EOFFSET_S4(\r)
lw $s5, EOFFSET_S5(\r)
lw $s6, EOFFSET_S6(\r)
lw $s7, EOFFSET_S7(\r)
lw $s8, EOFFSET_S8(\r)
#endif
lw $gp, EOFFSET_GP(\r)
lw $ra, EOFFSET_RA(\r)
lw $k1, EOFFSET_K1(\r)
175,9 → 152,9
ori $k0, $k0, %lo(supervisor_sp)
# Move $k0 (superveisor_sp)
lw $k0, 0($k0)
1:
1:
.endm
 
.org 0x0
kernel_image_start:
/* Load temporary stack */
184,31 → 161,12
lui $sp, %hi(end_stack)
ori $sp, $sp, %lo(end_stack)
/* $a1 contains physical address of bootinfo_t */
/* $a2 contains size of bootinfo_t */
beq $a2, $0, bootinfo_end
/* Not sure about this, but might be needed for PIC code???? */
/* Not sure about this, but might
be needed for PIC code */
lui $gp, 0x8000
lui $a3, %hi(bootinfo)
ori $a3, $a3, %lo(bootinfo)
/* $a1 contains physical address of bootinfo_t */
bootinfo_loop:
lw $v0, 0($a1)
sw $v0, 0($a3)
addi $a1, $a1, 4
addi $a3, $a3, 4
addi $a2, $a2, -4
bgtz $a2, bootinfo_loop
nop
bootinfo_end:
jal arch_pre_main
nop
228,8 → 186,8
 
exception_entry:
j exception_handler
nop
nop
 
exception_handler:
KERNEL_STACK_TO_K0
sub $k0, REGISTER_SPACE
238,17 → 196,17
mfc0 $k0, $cause
sra $k0, $k0, 0x2 # cp0_exc_cause() part 1
andi $k0, $k0, 0x1f # cp0_exc_cause() part 2
sub $k0, 8 # 8 = SYSCALL
sra $k0, $k0, 0x2 # cp0_exc_cause() part 1
andi $k0, $k0, 0x1f # cp0_exc_cause() part 2
sub $k0, 8 # 8 = SYSCALL
beqz $k0, syscall_shortcut
add $k0, 8 # Revert $k0 back to correct exc number
add $k0, 8 # Revert $k0 back to correct exc number
REGISTERS_STORE_AND_EXC_RESET $sp
move $a1, $sp
jal exc_dispatch # exc_dispatch(excno, register_space)
jal exc_dispatch # exc_dispatch(excno, register_space)
move $a0, $k0
 
REGISTERS_LOAD $sp
/branches/arm/kernel/arch/mips32/src/smp/order.c
File deleted
/branches/arm/kernel/arch/mips32/src/smp/smp.c
0,0 → 1,53
/*
* Copyright (c) 2009 Martin Decky
* 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 mips32
* @{
*/
/** @file
*/
 
#include <config.h>
#include <smp/smp.h>
#include <arch/arch.h>
 
#ifdef CONFIG_SMP
 
void smp_init(void)
{
config.cpu_count = cpu_count;
}
 
void kmp(void *arg __attribute__((unused)))
{
}
 
#endif /* CONFIG_SMP */
 
/** @}
*/
/branches/arm/kernel/arch/mips32/src/smp/dorder.c
0,0 → 1,47
/*
* Copyright (c) 2007 Martin Decky
* 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 mips32
* @{
*/
/** @file
*/
 
#include <arch/smp/dorder.h>
 
#define MSIM_DORDER_ADDRESS 0xB0000004
 
void ipi_broadcast_arch(int ipi)
{
#ifdef CONFIG_SMP
*((volatile unsigned int *) MSIM_DORDER_ADDRESS) = 0x7FFFFFFF;
#endif
}
 
/** @}
*/
/branches/arm/kernel/arch/mips32/src/fpu_context.c
40,7 → 40,7
 
void fpu_disable(void)
{
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
cp0_status_write(cp0_status_read() & ~cp0_status_fpu_bit);
#endif
}
47,7 → 47,7
 
void fpu_enable(void)
{
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
cp0_status_write(cp0_status_read() | cp0_status_fpu_bit);
#endif
}
/branches/arm/kernel/arch/mips32/src/cache.c
38,7 → 38,7
 
void cache_error(istate_t *istate)
{
panic("cache_error exception (epc=%p)\n", istate->epc);
panic("cache_error exception (epc=%p).", istate->epc);
}
 
/** @}
/branches/arm/kernel/arch/mips32/src/cpu/cpu.c
48,7 → 48,7
{ "MIPS", "R2000" }, /* 0x01 */
{ "MIPS", "R3000" }, /* 0x02 */
{ "MIPS", "R6000" }, /* 0x03 */
{ "MIPS", " R4000/R4400" }, /* 0x04 */
{ "MIPS", "R4000/R4400" }, /* 0x04 */
{ "LSI Logic", "R3000" }, /* 0x05 */
{ "MIPS", "R6000A" }, /* 0x06 */
{ "IDT", "3051/3052" }, /* 0x07 */
123,9 → 123,9
data = &imp_data[m->arch.imp_num];
}
 
printf("cpu%d: %s %s (rev=%d.%d, imp=%d)\n",
printf("cpu%u: %s %s (rev=%d.%d, imp=%d)\n",
m->id, data->vendor, data->model, m->arch.rev_num >> 4,
m->arch.rev_num & 0xf, m->arch.imp_num);
m->arch.rev_num & 0x0f, m->arch.imp_num);
}
 
/** @}
/branches/arm/kernel/arch/mips32/_link.ld.in
1,15 → 1,17
/*
* MIPS32 linker script
*
* MIPS32 linker script
*
* kernel text
* kernel data
*
*
*/
 
#undef mips
#define mips mips
 
#define KERNEL_LOAD_ADDRESS 0x80100000
 
OUTPUT_ARCH(mips)
 
ENTRY(kernel_image_start)
 
SECTIONS {
21,9 → 23,9
}
.data : {
kdata_start = .;
*(.data); /* initialized data */
*(.data); /* initialized data */
hardcoded_ktext_size = .;
LONG(ktext_end - ktext_start);
LONG(ktext_end - ktext_start);
hardcoded_kdata_size = .;
LONG(kdata_end - kdata_start);
hardcoded_load_address = .;
33,21 → 35,21
*(.reginfo);
*(.sbss);
*(.scommon);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
symbol_table = .;
*(symtab.*);
*(symtab.*);
}
_gp = . + 0x8000;
.lit8 : { *(.lit8) }
.lit4 : { *(.lit4) }
 
kdata_end = .;
 
/DISCARD/ : {
*(.mdebug*);
*(.pdr);
*(.comment);
*(.note);
*(.mdebug*);
*(.pdr);
*(.comment);
*(.note);
}
}
/branches/arm/kernel/arch/ia64/include/byteorder.h
File deleted
/branches/arm/kernel/arch/ia64/include/ski/ski.h
File deleted
/branches/arm/kernel/arch/ia64/include/mm/tlb.h
35,9 → 35,6
#ifndef KERN_ia64_TLB_H_
#define KERN_ia64_TLB_H_
 
#define tlb_arch_init()
#define tlb_print()
 
#include <arch/mm/page.h>
#include <arch/mm/asid.h>
#include <arch/interrupt.h>
46,8 → 43,8
/** Data and instruction Translation Register indices. */
#define DTR_KERNEL 0
#define ITR_KERNEL 0
#define DTR_KSTACK1 1
#define DTR_KSTACK2 2
#define DTR_KSTACK1 4
#define DTR_KSTACK2 5
 
/** Portion of TLB insertion format data structure. */
union tlb_entry {
79,12 → 76,12
extern void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry);
extern void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry);
 
extern void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr);
extern void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr);
extern void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr);
extern void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, size_t tr);
extern void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr);
extern void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr);
 
extern void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, index_t tr);
extern void dtr_purge(uintptr_t page, count_t width);
extern void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, size_t tr);
extern void dtr_purge(uintptr_t page, size_t width);
 
extern void dtc_pte_copy(pte_t *t);
extern void itc_pte_copy(pte_t *t);
95,6 → 92,7
extern void data_dirty_bit_fault(uint64_t vector, istate_t *istate);
extern void instruction_access_bit_fault(uint64_t vector, istate_t *istate);
extern void data_access_bit_fault(uint64_t vector, istate_t *istate);
extern void data_access_rights_fault(uint64_t vector, istate_t *istate);
extern void page_not_present(uint64_t vector, istate_t *istate);
 
#endif
/branches/arm/kernel/arch/ia64/include/mm/page.h
46,8 → 46,25
/** Bit width of the TLB-locked portion of kernel address space. */
#define KERNEL_PAGE_WIDTH 28 /* 256M */
#define IO_PAGE_WIDTH 26 /* 64M */
#define FW_PAGE_WIDTH 28 /* 256M */
 
#define USPACE_IO_PAGE_WIDTH 12 /* 4K */
 
 
/*
* Statically mapped IO spaces - offsets to 0xe...00 of virtual addresses
* because of "minimal virtual bits implemented is 51" it is possible to
* have values up to 0x0007000000000000
*/
 
/* Firmware area (bellow 4GB in phys mem) */
#define FW_OFFSET 0x00000000F0000000
/* Legacy IO space */
#define IO_OFFSET 0x0001000000000000
/* Videoram - now mapped to 0 as VGA text mode vram on 0xb8000 */
#define VIO_OFFSET 0x0002000000000000
 
 
#define PPN_SHIFT 12
 
#define VRN_SHIFT 61
62,8 → 79,8
 
#define REGION_REGISTERS 8
 
#define KA2PA(x) ((uintptr_t) (x-(VRN_KERNEL<<VRN_SHIFT)))
#define PA2KA(x) ((uintptr_t) (x+(VRN_KERNEL<<VRN_SHIFT)))
#define KA2PA(x) ((uintptr_t) (x - (VRN_KERNEL << VRN_SHIFT)))
#define PA2KA(x) ((uintptr_t) (x + (VRN_KERNEL << VRN_SHIFT)))
 
#define VHPT_WIDTH 20 /* 1M */
#define VHPT_SIZE (1 << VHPT_WIDTH)
223,7 → 240,7
*
* @return Current contents of rr[i].
*/
static inline uint64_t rr_read(index_t i)
static inline uint64_t rr_read(size_t i)
{
uint64_t ret;
ASSERT(i < REGION_REGISTERS);
236,7 → 253,7
* @param i Region register index.
* @param v Value to be written to rr[i].
*/
static inline void rr_write(index_t i, uint64_t v)
static inline void rr_write(size_t i, uint64_t v)
{
ASSERT(i < REGION_REGISTERS);
asm volatile (
/branches/arm/kernel/arch/ia64/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64mm
/** @addtogroup ia64mm
* @{
*/
/** @file
35,12 → 35,16
#ifndef KERN_ia64_FRAME_H_
#define KERN_ia64_FRAME_H_
 
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 14 /* 16K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
 
extern uintptr_t last_frame;
 
extern void frame_arch_init(void);
#define physmem_print()
 
/branches/arm/kernel/arch/ia64/include/mm/vhpt.h
44,8 → 44,8
{
vhpt_entry_t ventry;
ventry.word[0]=tentry.word[0];
ventry.word[1]=tentry.word[1];
ventry.word[0] = tentry.word[0];
ventry.word[1] = tentry.word[1];
return ventry;
}
/branches/arm/kernel/arch/ia64/include/types.h
54,8 → 54,6
} uint128_t;
 
typedef uint64_t size_t;
typedef uint64_t count_t;
typedef uint64_t index_t;
 
typedef uint64_t uintptr_t;
typedef uint64_t pfn_t;
65,10 → 63,13
typedef uint64_t unative_t;
typedef int64_t native_t;
 
typedef struct {
unative_t fnc;
unative_t gp;
} fncptr_t;
 
#define PRIp "lx" /**< Format for uintptr_t. */
#define PRIs "lu" /**< Format for size_t. */
#define PRIc "lu" /**< Format for count_t. */
#define PRIi "lu" /**< Format for index_t. */
 
#define PRId8 "d" /**< Format for int8_t. */
#define PRId16 "d" /**< Format for int16_t. */
/branches/arm/kernel/arch/ia64/include/arch.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64
/** @addtogroup ia64
* @{
*/
/** @file
37,8 → 37,10
 
#define LOADED_PROG_STACK_PAGES_NO 2
 
#include <arch/ski/ski.h>
#include <arch/drivers/ski.h>
 
extern void arch_pre_main(void);
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia64/include/drivers/i8042.h
File deleted
/branches/arm/kernel/arch/ia64/include/drivers/ega.h
File deleted
/branches/arm/kernel/arch/ia64/include/drivers/ski.h
0,0 → 1,56
/*
* Copyright (c) 2005 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 ia64
* @{
*/
/** @file
*/
 
#ifndef KERN_ia64_SKI_H_
#define KERN_ia64_SKI_H_
 
#include <console/chardev.h>
#include <proc/thread.h>
 
typedef struct {
thread_t *thread;
indev_t *srlnin;
} ski_instance_t;
 
extern void skiout_init(void);
 
extern ski_instance_t *skiin_init(void);
extern void skiin_wire(ski_instance_t *, indev_t *);
extern void ski_kbd_grab(void);
extern void ski_kbd_release(void);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/arch/ia64/include/drivers/kbd.h
0,0 → 1,46
/*
* Copyright (c) 2006 Jakub Jermar, Jakub Vana
* 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 ia6464
* @{
*/
/** @file
*/
 
#ifndef KERN_ia64_KBD_H_
#define KERN_ia64_KBD_H_
 
#define KBD_UNKNOWN 0
#define KBD_SKI 1
#define KBD_LEGACY 2
#define KBD_NS16550 3
 
#endif
 
/** @}
*/
/branches/arm/kernel/arch/ia64/include/drivers/it.h
41,7 → 41,7
* from firmware.
*
*/
#define IT_DELTA 100000
#define IT_DELTA it_delta
 
extern void it_init(void);
 
/branches/arm/kernel/arch/ia64/include/asm.h
36,29 → 36,72
#define KERN_ia64_ASM_H_
 
#include <config.h>
#include <typedefs.h>
#include <arch/types.h>
#include <arch/register.h>
 
 
#define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL
 
static inline void outb(uint64_t port,uint8_t v)
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v;
uintptr_t prt = (uintptr_t) port;
 
*((ioport8_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
uintptr_t prt = (uintptr_t) port;
 
static inline uint8_t inb(uint64_t port)
*((ioport16_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
uintptr_t prt = (uintptr_t) port;
 
*((ioport32_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12)))) = v;
 
asm volatile ("mf\n" ::: "memory");
}
 
return *((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 ))));
static inline uint8_t pio_read_8(ioport8_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((ioport8_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((ioport16_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
uintptr_t prt = (uintptr_t) port;
 
asm volatile ("mf\n" ::: "memory");
 
return *((ioport32_t *)(IA64_IOSPACE_ADDRESS +
((prt & 0xfff) | ((prt >> 2) << 12))));
}
 
/** Return base address of current stack
*
* Return the base address of the current stack.
69,9 → 112,14
{
uint64_t v;
 
asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
//I'm not sure why but this code bad inlines in scheduler,
//so THE shifts about 16B and causes kernel panic
//asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1)));
//return v;
return v;
//this code have the same meaning but inlines well
asm volatile ("mov %0 = r12" : "=r" (v) );
return v & (~(STACK_SIZE-1));
}
 
/** Return Processor State Register.
123,6 → 171,16
return v;
}
 
static inline uint64_t cr64_read(void)
{
uint64_t v;
asm volatile ("mov %0 = cr64\n" : "=r" (v));
return v;
}
 
 
/** Write ITC (Interval Timer Counter) register.
*
* @param v New counter value.
297,7 → 355,8
extern void cpu_sleep(void);
extern void asm_delay_loop(uint32_t t);
 
extern void switch_to_userspace(uintptr_t entry, uintptr_t sp, uintptr_t bsp, uintptr_t uspace_uarg, uint64_t ipsr, uint64_t rsc);
extern void switch_to_userspace(uintptr_t, uintptr_t, uintptr_t, uintptr_t,
uint64_t, uint64_t);
 
#endif
 
/branches/arm/kernel/arch/ia64/include/bootinfo.h
29,13 → 29,23
#ifndef KERN_ia64_BOOTINFO_H_
#define KERN_ia64_BOOTINFO_H_
 
#define BOOTINFO_ADDRESS 0x4401000
 
 
#define CONFIG_INIT_TASKS 32
 
#define MEMMAP_ITEMS 128
 
#define EFI_MEMMAP_FREE_MEM 0
#define EFI_MEMMAP_IO 1
#define EFI_MEMMAP_IO_PORTS 2
 
/** Size of buffer for storing task name in binit_task_t. */
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
typedef struct {
void *addr;
unsigned long size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} binit_task_t;
typedef struct {
43,9 → 53,24
binit_task_t tasks[CONFIG_INIT_TASKS];
} binit_t;
 
typedef struct {
unsigned int type;
unsigned long base;
unsigned long size;
}efi_memmap_item_t;
 
 
typedef struct {
binit_t taskmap;
 
efi_memmap_item_t memmap[MEMMAP_ITEMS];
unsigned int memmap_items;
 
unsigned long * sapic;
unsigned long sys_freq;
unsigned long freq_scale;
unsigned int wakeup_intno;
int hello_configured;
} bootinfo_t;
 
extern bootinfo_t *bootinfo;
/branches/arm/kernel/arch/ia64/include/interrupt.h
50,10 → 50,13
#define IVT_FIRST 0
 
/** External Interrupt vectors. */
 
#define VECTOR_TLB_SHOOTDOWN_IPI 0xf0
#define INTERRUPT_TIMER 255
#define IRQ_KBD 241
#define IRQ_MOUSE 252
#define IRQ_KBD (0x01 + LEGACY_INTERRUPT_BASE)
#define IRQ_MOUSE (0x0c + LEGACY_INTERRUPT_BASE)
#define INTERRUPT_SPURIOUS 15
#define LEGACY_INTERRUPT_BASE 0x20
 
/** General Exception codes. */
#define GE_ILLEGALOP 0
114,7 → 117,7
/*
* The following variables are defined only for break_instruction
* handler.
* handler.
*/
uint64_t in0;
uint64_t in1;
150,6 → 153,8
extern void external_interrupt(uint64_t vector, istate_t *istate);
extern void disabled_fp_register(uint64_t vector, istate_t *istate);
 
extern void trap_virtual_enable_irqs(uint16_t irqmask);
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia64/include/fpu_context.h
35,7 → 35,6
#ifndef KERN_ia64_FPU_CONTEXT_H_
#define KERN_ia64_FPU_CONTEXT_H_
 
#define ARCH_HAS_FPU 1
#define FPU_CONTEXT_ALIGN 16
 
#include <arch/types.h>
/branches/arm/kernel/arch/ia64/include/atomic.h
37,29 → 37,65
 
/** Atomic addition.
*
* @param val Atomic value.
* @param imm Value to add.
* @param val Atomic value.
* @param imm Value to add.
*
* @return Value before addition.
* @return Value before addition.
*/
static inline long atomic_add(atomic_t *val, int imm)
{
long v;
 
asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v), "+m" (val->count) : "i" (imm));
asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v),
"+m" (val->count) : "i" (imm));
return v;
}
 
static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); }
static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); }
 
static inline long atomic_preinc(atomic_t *val) { return atomic_add(val, 1) + 1; }
static inline long atomic_predec(atomic_t *val) { return atomic_add(val, -1) - 1; }
static inline uint64_t test_and_set(atomic_t *val) {
uint64_t v;
asm volatile (
"movl %0 = 0x01;;\n"
"xchg8 %0 = %1, %0;;\n"
: "=r" (v), "+m" (val->count)
);
return v;
}
 
static inline long atomic_postinc(atomic_t *val) { return atomic_add(val, 1); }
static inline long atomic_postdec(atomic_t *val) { return atomic_add(val, -1); }
 
static inline void atomic_inc(atomic_t *val)
{
atomic_add(val, 1);
}
 
static inline void atomic_dec(atomic_t *val)
{
atomic_add(val, -1);
}
 
static inline long atomic_preinc(atomic_t *val)
{
return atomic_add(val, 1) + 1;
}
 
static inline long atomic_predec(atomic_t *val)
{
return atomic_add(val, -1) - 1;
}
 
static inline long atomic_postinc(atomic_t *val)
{
return atomic_add(val, 1);
}
 
static inline long atomic_postdec(atomic_t *val)
{
return atomic_add(val, -1);
}
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia64/include/proc/task.h
31,14 → 31,19
*/
/** @file
*/
#include <proc/task.h>
 
#ifndef KERN_ia64_TASK_H_
#define KERN_ia64_TASK_H_
 
#include <adt/bitmap.h>
 
typedef struct {
bitmap_t *iomap;
} task_arch_t;
 
#define task_create_arch(t)
 
#define task_create_arch(t) { (t)->arch.iomap = NULL; }
#define task_destroy_arch(t)
 
#endif
/branches/arm/kernel/arch/ia64/include/register.h
40,11 → 40,11
#define PSR_I_MASK 0x4000
#define PSR_PK_MASK 0x8000
 
#define PSR_DT_MASK (1<<17)
#define PSR_RT_MASK (1<<27)
#define PSR_DT_MASK (1 << 17)
#define PSR_RT_MASK (1 << 27)
 
#define PSR_DFL_MASK (1<<18)
#define PSR_DFH_MASK (1<<19)
#define PSR_DFL_MASK (1 << 18)
#define PSR_DFH_MASK (1 << 19)
 
#define PSR_IT_MASK 0x0000001000000000
 
/branches/arm/kernel/arch/ia64/include/debug.h
1,5 → 1,5
/*
* Copyright (c) 2005
* Copyright (c) 2005 Ondrej Palkovsky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
/branches/arm/kernel/arch/ia64/include/cpu.h
38,6 → 38,7
#include <arch/types.h>
#include <arch/register.h>
#include <arch/asm.h>
#include <arch/bootinfo.h>
 
#define FAMILY_ITANIUM 0x7
#define FAMILY_ITANIUM2 0x1f
63,6 → 64,32
return v;
}
 
 
#define CR64_ID_SHIFT 24
#define CR64_ID_MASK 0xff000000
#define CR64_EID_SHIFT 16
#define CR64_EID_MASK 0xff0000
 
static inline int ia64_get_cpu_id(void)
{
uint64_t cr64=cr64_read();
return ((CR64_ID_MASK)&cr64)>>CR64_ID_SHIFT;
}
 
static inline int ia64_get_cpu_eid(void)
{
uint64_t cr64=cr64_read();
return ((CR64_EID_MASK)&cr64)>>CR64_EID_SHIFT;
}
 
 
static inline void ipi_send_ipi(int id, int eid, int intno)
{
(bootinfo->sapic)[2 * (id * 256 + eid)] = intno;
srlz_d();
 
}
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia64/src/ski/ski.c
File deleted
/branches/arm/kernel/arch/ia64/src/putchar.c
File deleted
/branches/arm/kernel/arch/ia64/src/ivt.S
536,7 → 536,7
HEAVYWEIGHT_HANDLER 0x5000 page_not_present
HEAVYWEIGHT_HANDLER 0x5100
HEAVYWEIGHT_HANDLER 0x5200
HEAVYWEIGHT_HANDLER 0x5300
HEAVYWEIGHT_HANDLER 0x5300 data_access_rights_fault
HEAVYWEIGHT_HANDLER 0x5400 general_exception
HEAVYWEIGHT_HANDLER 0x5500 disabled_fp_register
HEAVYWEIGHT_HANDLER 0x5600
/branches/arm/kernel/arch/ia64/src/mm/tlb.c
92,7 → 92,7
 
/** Invalidate entries belonging to an address space.
*
* @param asid Address space identifier.
* @param asid Address space identifier.
*/
void tlb_invalidate_asid(asid_t asid)
{
100,7 → 100,7
}
 
 
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
{
region_register rr;
bool restore_rr = false;
131,59 → 131,45
uint64_t ps;
switch (b) {
case 0: /*cnt 1-3*/
case 0: /* cnt 1 - 3 */
ps = PAGE_WIDTH;
break;
case 1: /*cnt 4-15*/
/*cnt=((cnt-1)/4)+1;*/
ps = PAGE_WIDTH+2;
va &= ~((1<<ps)-1);
case 1: /* cnt 4 - 15 */
ps = PAGE_WIDTH + 2;
va &= ~((1 << ps) - 1);
break;
case 2: /*cnt 16-63*/
/*cnt=((cnt-1)/16)+1;*/
ps = PAGE_WIDTH+4;
va &= ~((1<<ps)-1);
case 2: /* cnt 16 - 63 */
ps = PAGE_WIDTH + 4;
va &= ~((1 << ps) - 1);
break;
case 3: /*cnt 64-255*/
/*cnt=((cnt-1)/64)+1;*/
ps = PAGE_WIDTH+6;
va &= ~((1<<ps)-1);
case 3: /* cnt 64 - 255 */
ps = PAGE_WIDTH + 6;
va &= ~((1 << ps) - 1);
break;
case 4: /*cnt 256-1023*/
/*cnt=((cnt-1)/256)+1;*/
ps = PAGE_WIDTH+8;
va &= ~((1<<ps)-1);
case 4: /* cnt 256 - 1023 */
ps = PAGE_WIDTH + 8;
va &= ~((1 << ps) - 1);
break;
case 5: /*cnt 1024-4095*/
/*cnt=((cnt-1)/1024)+1;*/
ps = PAGE_WIDTH+10;
va &= ~((1<<ps)-1);
case 5: /* cnt 1024 - 4095 */
ps = PAGE_WIDTH + 10;
va &= ~((1 << ps) - 1);
break;
case 6: /*cnt 4096-16383*/
/*cnt=((cnt-1)/4096)+1;*/
ps = PAGE_WIDTH+12;
va &= ~((1<<ps)-1);
case 6: /* cnt 4096 - 16383 */
ps = PAGE_WIDTH + 12;
va &= ~((1 << ps) - 1);
break;
case 7: /*cnt 16384-65535*/
case 8: /*cnt 65536-(256K-1)*/
/*cnt=((cnt-1)/16384)+1;*/
ps = PAGE_WIDTH+14;
va &= ~((1<<ps)-1);
case 7: /* cnt 16384 - 65535 */
case 8: /* cnt 65536 - (256K - 1) */
ps = PAGE_WIDTH + 14;
va &= ~((1 << ps) - 1);
break;
default:
/*cnt=((cnt-1)/(16384*16))+1;*/
ps=PAGE_WIDTH+18;
va&=~((1<<ps)-1);
ps = PAGE_WIDTH + 18;
va &= ~((1 << ps) - 1);
break;
}
/*cnt+=(page!=va);*/
for(; va<(page+cnt*(PAGE_SIZE)); va += (1<<ps)) {
asm volatile (
"ptc.l %0,%1;;"
:
: "r" (va), "r" (ps<<2)
);
}
for(; va < (page + cnt * PAGE_SIZE); va += (1 << ps))
asm volatile ("ptc.l %0, %1;;" :: "r" (va), "r" (ps << 2));
srlz_d();
srlz_i();
196,9 → 182,10
 
/** Insert data into data translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
*/
void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
{
207,9 → 194,10
 
/** Insert data into instruction translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
*/
void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
{
218,10 → 206,12
 
/** Insert data into instruction or data translation cache.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param dtc If true, insert into data translation cache, use instruction translation cache otherwise.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param dtc If true, insert into data translation cache, use
* instruction translation cache otherwise.
*/
void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc)
{
244,19 → 234,20
}
asm volatile (
"mov r8=psr;;\n"
"mov r8 = psr;;\n"
"rsm %0;;\n" /* PSR_IC_MASK */
"srlz.d;;\n"
"srlz.i;;\n"
"mov cr.ifa=%1\n" /* va */
"mov cr.itir=%2;;\n" /* entry.word[1] */
"cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */
"mov cr.ifa = %1\n" /* va */
"mov cr.itir = %2;;\n" /* entry.word[1] */
"cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */
"(p6) itc.i %3;;\n"
"(p7) itc.d %3;;\n"
"mov psr.l=r8;;\n"
"mov psr.l = r8;;\n"
"srlz.d;;\n"
:
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc)
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]),
"r" (entry.word[0]), "r" (dtc)
: "p6", "p7", "r8"
);
269,12 → 260,14
 
/** Insert data into instruction translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param tr Translation register.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param tr Translation register.
*/
void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr)
void
itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr)
{
tr_mapping_insert(va, asid, entry, false, tr);
}
281,12 → 274,14
 
/** Insert data into data translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param tr Translation register.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param tr Translation register.
*/
void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr)
void
dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr)
{
tr_mapping_insert(va, asid, entry, true, tr);
}
293,13 → 288,17
 
/** Insert data into instruction or data translation register.
*
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion format.
* @param dtr If true, insert into data translation register, use instruction translation register otherwise.
* @param tr Translation register.
* @param va Virtual page address.
* @param asid Address space identifier.
* @param entry The rest of TLB entry as required by TLB insertion
* format.
* @param dtr If true, insert into data translation register, use
* instruction translation register otherwise.
* @param tr Translation register.
*/
void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr)
void
tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr,
size_t tr)
{
region_register rr;
bool restore_rr = false;
320,19 → 319,20
}
 
asm volatile (
"mov r8=psr;;\n"
"mov r8 = psr;;\n"
"rsm %0;;\n" /* PSR_IC_MASK */
"srlz.d;;\n"
"srlz.i;;\n"
"mov cr.ifa=%1\n" /* va */
"mov cr.itir=%2;;\n" /* entry.word[1] */
"cmp.eq p6,p7=%5,r0;;\n" /* decide between itr and dtr */
"(p6) itr.i itr[%4]=%3;;\n"
"(p7) itr.d dtr[%4]=%3;;\n"
"mov psr.l=r8;;\n"
"mov cr.ifa = %1\n" /* va */
"mov cr.itir = %2;;\n" /* entry.word[1] */
"cmp.eq p6,p7 = %5,r0;;\n" /* decide between itr and dtr */
"(p6) itr.i itr[%4] = %3;;\n"
"(p7) itr.d dtr[%4] = %3;;\n"
"mov psr.l = r8;;\n"
"srlz.d;;\n"
:
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr)
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]),
"r" (entry.word[0]), "r" (tr), "r" (dtr)
: "p6", "p7", "r8"
);
345,12 → 345,15
 
/** Insert data into DTLB.
*
* @param page Virtual page address including VRN bits.
* @param frame Physical frame address.
* @param dtr If true, insert into data translation register, use data translation cache otherwise.
* @param tr Translation register if dtr is true, ignored otherwise.
* @param page Virtual page address including VRN bits.
* @param frame Physical frame address.
* @param dtr If true, insert into data translation register, use data
* translation cache otherwise.
* @param tr Translation register if dtr is true, ignored otherwise.
*/
void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, index_t tr)
void
dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr,
size_t tr)
{
tlb_entry_t entry;
376,18 → 379,18
*
* Purge DTR entries used by the kernel.
*
* @param page Virtual page address including VRN bits.
* @param width Width of the purge in bits.
* @param page Virtual page address including VRN bits.
* @param width Width of the purge in bits.
*/
void dtr_purge(uintptr_t page, count_t width)
void dtr_purge(uintptr_t page, size_t width)
{
asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width<<2));
asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width << 2));
}
 
 
/** Copy content of PTE into data translation cache.
*
* @param t PTE.
* @param t PTE.
*/
void dtc_pte_copy(pte_t *t)
{
413,7 → 416,7
 
/** Copy content of PTE into instruction translation cache.
*
* @param t PTE.
* @param t PTE.
*/
void itc_pte_copy(pte_t *t)
{
440,8 → 443,8
 
/** Instruction TLB fault handler for faults with VHPT turned off.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void alternate_instruction_tlb_fault(uint64_t vector, istate_t *istate)
{
469,16 → 472,77
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
fault_if_from_uspace(istate,"Page fault at %p.",va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
}
 
static int is_io_page_accessible(int page)
{
if (TASK->arch.iomap)
return bitmap_get(TASK->arch.iomap, page);
else
return 0;
}
 
#define IO_FRAME_BASE 0xFFFFC000000
 
/**
* There is special handling of memory mapped legacy io, because of 4KB sized
* access for userspace.
*
* @param va Virtual address of page fault.
* @param istate Structure with saved interruption state.
*
* @return One on success, zero on failure.
*/
static int try_memmap_io_insertion(uintptr_t va, istate_t *istate)
{
if ((va >= IO_OFFSET ) && (va < IO_OFFSET + (1 << IO_PAGE_WIDTH))) {
if (TASK) {
uint64_t io_page = (va & ((1 << IO_PAGE_WIDTH) - 1)) >>
USPACE_IO_PAGE_WIDTH;
 
if (is_io_page_accessible(io_page)) {
uint64_t page, frame;
 
page = IO_OFFSET +
(1 << USPACE_IO_PAGE_WIDTH) * io_page;
frame = IO_FRAME_BASE +
(1 << USPACE_IO_PAGE_WIDTH) * io_page;
 
tlb_entry_t entry;
entry.word[0] = 0;
entry.word[1] = 0;
entry.p = true; /* present */
entry.ma = MA_UNCACHEABLE;
entry.a = true; /* already accessed */
entry.d = true; /* already dirty */
entry.pl = PL_USER;
entry.ar = AR_READ | AR_WRITE;
entry.ppn = frame >> PPN_SHIFT;
entry.ps = USPACE_IO_PAGE_WIDTH;
dtc_mapping_insert(page, TASK->as->asid, entry);
return 1;
} else {
fault_if_from_uspace(istate,
"IO access fault at %p.", va);
}
}
}
return 0;
}
 
/** Data TLB fault handler for faults with VHPT turned off.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void alternate_data_tlb_fault(uint64_t vector, istate_t *istate)
{
511,13 → 575,17
dtc_pte_copy(t);
page_table_unlock(AS, true);
} else {
page_table_unlock(AS, true);
if (try_memmap_io_insertion(va, istate))
return;
/*
* Forward the page fault to the address space page fault handler.
* Forward the page fault to the address space page fault
* handler.
*/
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
fault_if_from_uspace(istate,"Page fault at %p.",va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
}
526,18 → 594,18
*
* This fault should not occur.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_nested_tlb_fault(uint64_t vector, istate_t *istate)
{
panic("%s\n", __func__);
panic("%s.", __func__);
}
 
/** Data Dirty bit fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_dirty_bit_fault(uint64_t vector, istate_t *istate)
{
562,10 → 630,9
dtc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
t->d = true;
dtc_pte_copy(t);
fault_if_from_uspace(istate,"Page fault at %p.",va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
page_table_unlock(AS, true);
573,8 → 640,8
 
/** Instruction access bit fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void instruction_access_bit_fault(uint64_t vector, istate_t *istate)
{
599,10 → 666,9
itc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
t->a = true;
itc_pte_copy(t);
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
page_table_unlock(AS, true);
636,15 → 702,45
dtc_pte_copy(t);
} else {
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip);
t->a = true;
itc_pte_copy(t);
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
}
page_table_unlock(AS, true);
}
 
/** Data access rights fault handler.
*
* @param vector Interruption vector.
* @param istate Structure with saved interruption state.
*/
void data_access_rights_fault(uint64_t vector, istate_t *istate)
{
region_register rr;
rid_t rid;
uintptr_t va;
pte_t *t;
 
va = istate->cr_ifa; /* faulting address */
rr.word = rr_read(VA2VRN(va));
rid = rr.map.rid;
 
/*
* Assume a write to a read-only page.
*/
page_table_lock(AS, true);
t = page_mapping_find(AS, va);
ASSERT(t && t->p);
ASSERT(!t->w);
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid,
istate->cr_iip);
}
page_table_unlock(AS, true);
}
 
/** Page not present fault handler.
*
* @param vector Interruption vector.
678,11 → 774,19
} else {
page_table_unlock(AS, true);
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) {
fault_if_from_uspace(istate,"Page fault at %p",va);
panic("%s: va=%p, rid=%d\n", __func__, va, rid);
fault_if_from_uspace(istate, "Page fault at %p.", va);
panic("%s: va=%p, rid=%d.", __func__, va, rid);
}
}
}
 
void tlb_arch_init(void)
{
}
 
void tlb_print(void)
{
}
 
/** @}
*/
/branches/arm/kernel/arch/ia64/src/mm/vhpt.c
41,7 → 41,8
 
uintptr_t vhpt_set_up(void)
{
vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH, FRAME_KA | FRAME_ATOMIC);
vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH,
FRAME_KA | FRAME_ATOMIC);
if (!vhpt_base)
panic("Kernel configured with VHPT but no memory for table.");
vhpt_invalidate_all();
52,7 → 53,7
void vhpt_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry)
{
region_register rr_save, rr;
index_t vrn;
size_t vrn;
rid_t rid;
uint64_t tag;
 
/branches/arm/kernel/arch/ia64/src/mm/page.c
27,7 → 27,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64mm
/** @addtogroup ia64mm
* @{
*/
/** @file
47,6 → 47,7
#include <arch/asm.h>
#include <arch/barrier.h>
#include <memstr.h>
#include <align.h>
 
static void set_environment(void);
 
62,9 → 63,9
void set_environment(void)
{
region_register rr;
pta_register pta;
pta_register pta;
int i;
#ifdef CONFIG_VHPT
#ifdef CONFIG_VHPT
uintptr_t vhpt_base;
#endif
 
122,15 → 123,15
*
* Interrupts must be disabled.
*
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
*
* @return VHPT entry address.
* @return VHPT entry address.
*/
vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid)
{
region_register rr_save, rr;
index_t vrn;
size_t vrn;
rid_t rid;
vhpt_entry_t *v;
 
166,15 → 167,16
*
* Interrupts must be disabled.
*
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
* @param page Address of virtual page including VRN bits.
* @param asid Address space identifier.
*
* @return True if page and asid match the page and asid of t, false otherwise.
* @return True if page and asid match the page and asid of t,
* false otherwise.
*/
bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v)
{
region_register rr_save, rr;
index_t vrn;
size_t vrn;
rid_t rid;
bool match;
 
210,15 → 212,18
/** Set up one VHPT entry.
*
* @param v VHPT entry to be set up.
* @param page Virtual address of the page mapped by the entry.
* @param asid Address space identifier of the address space to which page belongs.
* @param frame Physical address of the frame to wich page is mapped.
* @param flags Different flags for the mapping.
* @param page Virtual address of the page mapped by the entry.
* @param asid Address space identifier of the address space to which
* page belongs.
* @param frame Physical address of the frame to wich page is mapped.
* @param flags Different flags for the mapping.
*/
void vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame, int flags)
void
vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame,
int flags)
{
region_register rr_save, rr;
index_t vrn;
size_t vrn;
rid_t rid;
uint64_t tag;
 
249,7 → 254,8
v->word[3] = 0;
v->present.p = true;
v->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE;
v->present.ma = (flags & PAGE_CACHEABLE) ?
MA_WRITEBACK : MA_UNCACHEABLE;
v->present.a = false; /* not accessed */
v->present.d = false; /* not dirty */
v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL;
262,5 → 268,11
v->present.tag.tag_word = tag;
}
 
uintptr_t hw_map(uintptr_t physaddr, size_t size __attribute__ ((unused)))
{
/* THIS is a dirty hack. */
return (uintptr_t)((uint64_t)(PA2KA(physaddr)) + VIO_OFFSET);
}
 
/** @}
*/
/branches/arm/kernel/arch/ia64/src/mm/frame.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64mm
/** @addtogroup ia64mm
* @{
*/
/** @file
36,26 → 36,55
#include <mm/frame.h>
#include <config.h>
#include <panic.h>
#include <arch/bootinfo.h>
#include <align.h>
#include <macros.h>
 
/*
* This is Ski-specific and certainly not sufficient
* for real ia64 systems that provide memory map.
*/
#define MEMORY_SIZE (64 * 1024 * 1024)
#define MEMORY_BASE (64 * 1024 * 1024)
#define KERNEL_RESERVED_AREA_BASE (0x4400000)
#define KERNEL_RESERVED_AREA_SIZE (16 * 1024 * 1024)
 
#define ROM_BASE 0xa0000 //For ski
#define ROM_SIZE (384 * 1024) //For ski
void poke_char(int x,int y,char ch, char c);
#define ROM_BASE 0xa0000 /* for simulators */
#define ROM_SIZE (384 * 1024) /* for simulators */
 
#define MIN_ZONE_SIZE (64 * 1024)
 
#define MINCONF 1
 
uintptr_t last_frame = 0;
 
void frame_arch_init(void)
{
zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0);
/*
* Blacklist ROM regions.
*/
frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE));
if (config.cpu_active == 1) {
unsigned int i;
for (i = 0; i < bootinfo->memmap_items; i++) {
if (bootinfo->memmap[i].type == EFI_MEMMAP_FREE_MEM) {
uint64_t base = bootinfo->memmap[i].base;
uint64_t size = bootinfo->memmap[i].size;
uint64_t abase = ALIGN_UP(base, FRAME_SIZE);
 
if (size > FRAME_SIZE)
size -= abase - base;
 
if (size > MIN_ZONE_SIZE) {
zone_create(abase >> FRAME_WIDTH,
size >> FRAME_WIDTH,
max(MINCONF, abase >> FRAME_WIDTH),
0);
}
if (abase + size > last_frame)
last_frame = abase + size;
}
}
/*
* Blacklist ROM regions.
*/
frame_mark_unavailable(ADDR2PFN(ROM_BASE),
SIZE2FRAMES(ROM_SIZE));
 
frame_mark_unavailable(ADDR2PFN(KERNEL_RESERVED_AREA_BASE),
SIZE2FRAMES(KERNEL_RESERVED_AREA_SIZE));
}
}
 
/** @}
/branches/arm/kernel/arch/ia64/src/mm/as.c
68,7 → 68,7
continue;
rr.word = rr_read(i);
rr.map.ve = false; /* disable VHPT walker */
rr.map.ve = false; /* disable VHPT walker */
rr.map.rid = ASID2RID(as->asid, i);
rr.map.ps = PAGE_WIDTH;
rr_write(i, rr.word);
/branches/arm/kernel/arch/ia64/src/drivers/ega.c
File deleted
/branches/arm/kernel/arch/ia64/src/drivers/ski.c
0,0 → 1,246
/*
* Copyright (c) 2005 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 ia64
* @{
*/
/** @file
*/
 
#include <arch/drivers/ski.h>
#include <console/console.h>
#include <console/chardev.h>
#include <sysinfo/sysinfo.h>
#include <arch/types.h>
#include <proc/thread.h>
#include <synch/spinlock.h>
#include <arch/asm.h>
#include <arch/drivers/kbd.h>
#include <string.h>
#include <arch.h>
 
enum {
/** Interval between polling in microseconds */
POLL_INTERVAL = 10000, /* 0.01 s */
 
/** Max. number of characters to pull out at a time */
POLL_LIMIT = 30,
 
SKI_INIT_CONSOLE = 20,
SKI_GETCHAR = 21,
SKI_PUTCHAR = 31
};
 
static void ski_putchar(outdev_t *, const wchar_t, bool);
 
static outdev_operations_t skiout_ops = {
.write = ski_putchar
};
 
static outdev_t skiout; /**< Ski output device. */
static bool initialized = false;
static bool kbd_disabled = false;
 
/** Initialize debug console
*
* Issue SSC (Simulator System Call) to
* to open debug console.
*
*/
static void ski_init(void)
{
if (initialized)
return;
asm volatile (
"mov r15 = %0\n"
"break 0x80000\n"
:
: "i" (SKI_INIT_CONSOLE)
: "r15", "r8"
);
initialized = true;
}
 
static void ski_do_putchar(const wchar_t ch)
{
asm volatile (
"mov r15 = %[cmd]\n"
"mov r32 = %[ch]\n" /* r32 is in0 */
"break 0x80000\n" /* modifies r8 */
:
: [cmd] "i" (SKI_PUTCHAR), [ch] "r" (ch)
: "r15", "in0", "r8"
);
}
 
/** Display character on debug console
*
* Use SSC (Simulator System Call) to
* display character on debug console.
*
* @param dev Character device.
* @param ch Character to be printed.
* @param silent Whether the output should be silenced.
*
*/
static void ski_putchar(outdev_t *dev, const wchar_t ch, bool silent)
{
if (!silent) {
if (ascii_check(ch)) {
if (ch == '\n')
ski_do_putchar('\r');
ski_do_putchar(ch);
} else
ski_do_putchar(U_SPECIAL);
}
}
 
void skiout_init(void)
{
ski_init();
outdev_initialize("skiout", &skiout, &skiout_ops);
stdout = &skiout;
sysinfo_set_item_val("fb", NULL, false);
}
 
/** Ask debug console if a key was pressed.
*
* Use SSC (Simulator System Call) to
* get character from debug console.
*
* This call is non-blocking.
*
* @return ASCII code of pressed key or 0 if no key pressed.
*
*/
static wchar_t ski_getchar(void)
{
uint64_t ch;
asm volatile (
"mov r15 = %1\n"
"break 0x80000;;\n" /* modifies r8 */
"mov %0 = r8;;\n"
: "=r" (ch)
: "i" (SKI_GETCHAR)
: "r15", "r8"
);
return (wchar_t) ch;
}
 
/** Ask keyboard if a key was pressed.
*
* If so, it will repeat and pull up to POLL_LIMIT characters.
*/
static void poll_keyboard(ski_instance_t *instance)
{
wchar_t ch;
int count;
 
if (kbd_disabled)
return;
 
count = POLL_LIMIT;
 
while (count > 0) {
ch = ski_getchar();
 
if (ch == '\0')
break;
 
indev_push_character(instance->srlnin, ch);
--count;
}
}
 
/** Kernel thread for polling keyboard. */
static void kskipoll(void *arg)
{
ski_instance_t *instance = (ski_instance_t *) arg;
while (true) {
if (!silent)
poll_keyboard(instance);
thread_usleep(POLL_INTERVAL);
}
}
 
ski_instance_t *skiin_init(void)
{
ski_init();
ski_instance_t *instance =
malloc(sizeof(ski_instance_t), FRAME_ATOMIC);
if (instance) {
instance->thread = thread_create(kskipoll, instance, TASK, 0,
"kskipoll", true);
if (!instance->thread) {
free(instance);
return NULL;
}
instance->srlnin = NULL;
}
return instance;
}
 
void skiin_wire(ski_instance_t *instance, indev_t *srlnin)
{
ASSERT(instance);
ASSERT(srlnin);
instance->srlnin = srlnin;
thread_ready(instance->thread);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.type", NULL, KBD_SKI);
}
 
void ski_kbd_grab(void)
{
kbd_disabled = false;
}
 
void ski_kbd_release(void)
{
kbd_disabled = true;
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/arch/ia64/src/drivers/it.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia64
/** @addtogroup ia64
* @{
*/
/** @file
44,25 → 44,44
#include <ddi/device.h>
#include <arch.h>
 
#define IT_SERVICE_CLOCKS 64
#define IT_SERVICE_CLOCKS 64
 
#define FREQ_NUMERATOR_SHIFT 32
#define FREQ_NUMERATOR_MASK 0xffffffff00000000ULL
 
#define FREQ_DENOMINATOR_SHIFT 0
#define FREQ_DENOMINATOR_MASK 0xffffffffULL
 
uint64_t it_delta;
 
static irq_t it_irq;
 
static irq_ownership_t it_claim(void);
static void it_interrupt(irq_t *irq, void *arg, ...);
static irq_ownership_t it_claim(irq_t *);
static void it_interrupt(irq_t *);
 
/** Initialize Interval Timer. */
void it_init(void)
{
cr_itv_t itv;
 
irq_initialize(&it_irq);
it_irq.inr = INTERRUPT_TIMER;
it_irq.devno = device_assign_devno();
it_irq.claim = it_claim;
it_irq.handler = it_interrupt;
irq_register(&it_irq);
 
if (config.cpu_active == 1) {
irq_initialize(&it_irq);
it_irq.inr = INTERRUPT_TIMER;
it_irq.devno = device_assign_devno();
it_irq.claim = it_claim;
it_irq.handler = it_interrupt;
irq_register(&it_irq);
uint64_t base_freq;
base_freq = ((bootinfo->freq_scale) & FREQ_NUMERATOR_MASK) >>
FREQ_NUMERATOR_SHIFT;
base_freq *= bootinfo->sys_freq;
base_freq /= ((bootinfo->freq_scale) & FREQ_DENOMINATOR_MASK) >>
FREQ_DENOMINATOR_SHIFT;
it_delta = base_freq / HZ;
}
/* initialize Interval Timer external interrupt vector */
itv.value = itv_read();
itv.vector = INTERRUPT_TIMER;
85,13 → 104,13
*
* @return Always IRQ_ACCEPT.
*/
irq_ownership_t it_claim(void)
irq_ownership_t it_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Process Interval Timer interrupt. */
void it_interrupt(irq_t *irq, void *arg, ...)
void it_interrupt(irq_t *irq)
{
int64_t c;
int64_t m;
/branches/arm/kernel/arch/ia64/src/smp/smp.c
0,0 → 1,167
/*
* Copyright (c) 2005 Jakub Vana
* 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 ia64
* @{
*/
/** @file
*/
 
#include <arch.h>
#include <arch/drivers/ski.h>
#include <arch/drivers/it.h>
#include <arch/interrupt.h>
#include <arch/barrier.h>
#include <arch/asm.h>
#include <arch/register.h>
#include <arch/types.h>
#include <arch/context.h>
#include <arch/stack.h>
#include <arch/mm/page.h>
#include <mm/as.h>
#include <config.h>
#include <userspace.h>
#include <console/console.h>
#include <proc/uarg.h>
#include <syscall/syscall.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#include <arch/bootinfo.h>
#include <smp/smp.h>
#include <smp/ipi.h>
#include <arch/atomic.h>
#include <panic.h>
#include <print.h>
 
#ifdef CONFIG_SMP
 
extern char cpu_by_id_eid_list[256][256];
 
static void sapic_init(void)
{
bootinfo->sapic = (unative_t *)(PA2KA((unative_t)(bootinfo->sapic)) |
FW_OFFSET);
}
 
static void ipi_broadcast_arch_all(int ipi)
{
int id, eid;
int myid, myeid;
myid = ia64_get_cpu_id();
myeid = ia64_get_cpu_eid();
for (id = 0; id < 256; id++)
for (eid = 0; eid < 256; eid++)
if ((id != myid) || (eid != myeid))
ipi_send_ipi(id, eid, ipi);
}
 
void ipi_broadcast_arch(int ipi )
{
int id, eid;
int myid, myeid;
myid = ia64_get_cpu_id();
myeid = ia64_get_cpu_eid();
 
for (id = 0; id < 256; id++)
for (eid = 0; eid < 256; eid++)
if ((id != myid) || (eid != myeid))
if (cpu_by_id_eid_list[id][eid])
ipi_send_ipi(id, eid, ipi);
}
 
void smp_init(void)
{
if (!bootinfo->hello_configured)
return;
/*
* If we have not got system prepared by hello, we are not able to start
* AP's. This means we are running on a simulator.
*/
sapic_init();
ipi_broadcast_arch_all(bootinfo->wakeup_intno);
volatile long long brk;
for (brk = 0; brk < 100LL * 1024LL * 1024LL; brk++)
; /* wait a while before CPUs starts */
 
config.cpu_count = 0;
int id, eid;
for (id = 0; id < 256; id++)
for (eid = 0; eid < 256; eid++)
if (cpu_by_id_eid_list[id][eid] == 1) {
config.cpu_count++;
cpu_by_id_eid_list[id][eid] = 2;
}
}
 
void kmp(void *arg __attribute__((unused)))
{
int id, eid;
int myid, myeid;
myid = ia64_get_cpu_id();
myeid = ia64_get_cpu_eid();
 
for (id = 0; id < 256; id++)
for (eid = 0; eid < 256; eid++)
if ((id != myid) || (eid != myeid))
if (cpu_by_id_eid_list[id][eid] != 0) {
if (cpu_by_id_eid_list[id][eid] == 1) {
printf("Found Late CPU ID:%d "
"EDI:%d Not added to "
"system!!!\n", id, eid);
continue;
}
cpu_by_id_eid_list[id][eid] = 3;
/*
* There may be just one AP being
* initialized at the time. After
* it comes completely up, it is
* supposed to wake us up.
*/
if (waitq_sleep_timeout(
&ap_completion_wq, 1000000,
SYNCH_FLAGS_NONE) ==
ESYNCH_TIMEOUT) {
printf("%s: waiting for cpu "
"ID:%d EID:%d timed out\n",
__FUNCTION__, id, eid);
}
}
}
 
#endif
 
/** @}
*/
 
/branches/arm/kernel/arch/ia64/src/ia64.c
33,7 → 33,7
*/
 
#include <arch.h>
#include <arch/ski/ski.h>
#include <arch/drivers/ski.h>
#include <arch/drivers/it.h>
#include <arch/interrupt.h>
#include <arch/barrier.h>
50,64 → 50,91
#include <proc/uarg.h>
#include <syscall/syscall.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#include <arch/drivers/ega.h>
#include <arch/bootinfo.h>
#include <genarch/kbd/i8042.h>
#include <genarch/drivers/legacy/ia32/io.h>
#include <genarch/drivers/ega/ega.h>
#include <genarch/kbrd/kbrd.h>
#include <genarch/srln/srln.h>
#include <genarch/drivers/i8042/i8042.h>
#include <genarch/drivers/ns16550/ns16550.h>
#include <arch/drivers/kbd.h>
#include <smp/smp.h>
#include <smp/ipi.h>
#include <arch/atomic.h>
#include <panic.h>
#include <print.h>
#include <sysinfo/sysinfo.h>
#include <string.h>
 
/* NS16550 as a COM 1 */
#define NS16550_IRQ (4 + LEGACY_INTERRUPT_BASE)
 
bootinfo_t *bootinfo;
 
static uint64_t iosapic_base = 0xfec00000;
 
/** Performs ia64-specific initialization before main_bsp() is called. */
void arch_pre_main(void)
{
/* Setup usermode init tasks. */
 
//#ifdef I460GX
unsigned int i;
init.cnt = bootinfo->taskmap.count;
for (i = 0; i < init.cnt; i++) {
init.tasks[i].addr = ((unsigned long) bootinfo->taskmap.tasks[i].addr) | VRN_MASK;
init.tasks[i].addr =
((unsigned long) bootinfo->taskmap.tasks[i].addr) |
VRN_MASK;
init.tasks[i].size = bootinfo->taskmap.tasks[i].size;
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
bootinfo->taskmap.tasks[i].name);
}
/*
#else
init.cnt = 8;
init.tasks[0].addr = INIT0_ADDRESS;
init.tasks[0].size = INIT0_SIZE;
init.tasks[1].addr = INIT0_ADDRESS + 0x400000;
init.tasks[1].size = INIT0_SIZE;
init.tasks[2].addr = INIT0_ADDRESS + 0x800000;
init.tasks[2].size = INIT0_SIZE;
init.tasks[3].addr = INIT0_ADDRESS + 0xc00000;
init.tasks[3].size = INIT0_SIZE;
init.tasks[4].addr = INIT0_ADDRESS + 0x1000000;
init.tasks[4].size = INIT0_SIZE;
init.tasks[5].addr = INIT0_ADDRESS + 0x1400000;
init.tasks[5].size = INIT0_SIZE;
init.tasks[6].addr = INIT0_ADDRESS + 0x1800000;
init.tasks[6].size = INIT0_SIZE;
init.tasks[7].addr = INIT0_ADDRESS + 0x1c00000;
init.tasks[7].size = INIT0_SIZE;
#endif*/
}
 
void arch_pre_mm_init(void)
{
/* Set Interruption Vector Address (i.e. location of interruption vector table). */
/*
* Set Interruption Vector Address (i.e. location of interruption vector
* table).
*/
iva_write((uintptr_t) &ivt);
srlz_d();
}
 
static void iosapic_init(void)
{
uint64_t IOSAPIC = PA2KA((unative_t)(iosapic_base)) | FW_OFFSET;
int i;
int myid, myeid;
myid = ia64_get_cpu_id();
myeid = ia64_get_cpu_eid();
 
for (i = 0; i < 16; i++) {
if (i == 2)
continue; /* Disable Cascade interrupt */
((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i;
srlz_d();
((uint32_t *)(IOSAPIC + 0x10))[0] = LEGACY_INTERRUPT_BASE + i;
srlz_d();
((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i + 1;
srlz_d();
((uint32_t *)(IOSAPIC + 0x10))[0] = myid << (56 - 32) |
myeid << (48 - 32);
srlz_d();
}
 
}
 
void arch_post_mm_init(void)
{
irq_init(INR_COUNT, INR_COUNT);
#ifdef SKI
ski_init_console();
#else
ega_init();
#endif
if (config.cpu_active == 1) {
iosapic_init();
irq_init(INR_COUNT, INR_COUNT);
}
it_init();
}
 
119,51 → 146,73
{
}
 
 
#ifdef I460GX
#define POLL_INTERVAL 50000 /* 50 ms */
/** Kernel thread for polling keyboard. */
static void i8042_kkbdpoll(void *arg)
void arch_post_smp_init(void)
{
while (1) {
i8042_poll();
thread_usleep(POLL_INTERVAL);
#ifdef MACHINE_ski
ski_instance_t *ski_instance = skiin_init();
if (ski_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
skiin_wire(ski_instance, srln);
}
}
}
skiout_init();
#endif
 
void arch_post_smp_init(void)
{
 
if (config.cpu_active == 1) {
/*
* Create thread that polls keyboard.
*/
#ifdef SKI
thread_t *t;
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("cannot create kkbdpoll\n");
thread_ready(t);
#endif
 
#ifdef I460GX
devno_t kbd = device_assign_devno();
devno_t mouse = device_assign_devno();
/* keyboard controller */
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE);
 
thread_t *t;
t = thread_create(i8042_kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("cannot create kkbdpoll\n");
thread_ready(t);
 
#ifdef CONFIG_EGA
ega_init(EGA_BASE, EGA_VIDEORAM);
#endif
 
#ifdef CONFIG_NS16550
ns16550_instance_t *ns16550_instance
= ns16550_init((ns16550_t *) NS16550_BASE, NS16550_IRQ, NULL, NULL);
if (ns16550_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
ns16550_wire(ns16550_instance, srln);
}
}
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, NS16550_IRQ);
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
sysinfo_set_item_val("kbd.address.physical", NULL,
(uintptr_t) NS16550_BASE);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) NS16550_BASE);
#endif
#ifdef CONFIG_I8042
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
if (i8042_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
i8042_wire(i8042_instance, kbrd);
}
}
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
sysinfo_set_item_val("kbd.type", NULL, KBD_LEGACY);
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
sysinfo_set_item_val("ia64_iospace", NULL, true);
sysinfo_set_item_val("ia64_iospace.address", NULL, true);
sysinfo_set_item_val("ia64_iospace.address.virtual", NULL, IO_OFFSET);
}
 
 
/** Enter userspace and never return. */
void userspace(uspace_arg_t *kernel_uarg)
{
172,26 → 221,25
 
psr.value = psr_read();
psr.cpl = PL_USER;
psr.i = true; /* start with interrupts enabled */
psr.i = true; /* start with interrupts enabled */
psr.ic = true;
psr.ri = 0; /* start with instruction #0 */
psr.bn = 1; /* start in bank 0 */
psr.ri = 0; /* start with instruction #0 */
psr.bn = 1; /* start in bank 0 */
 
asm volatile ("mov %0 = ar.rsc\n" : "=r" (rsc.value));
rsc.loadrs = 0;
rsc.be = false;
rsc.pl = PL_USER;
rsc.mode = 3; /* eager mode */
rsc.mode = 3; /* eager mode */
 
switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE,
(uintptr_t) kernel_uarg->uspace_uarg,
psr.value, rsc.value);
((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE -
ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE,
(uintptr_t) kernel_uarg->uspace_uarg, psr.value, rsc.value);
 
while (1) {
while (1)
;
}
}
 
/** Set thread-local-storage pointer.
208,16 → 256,17
*/
void arch_grab_console(void)
{
#ifdef SKI
#ifdef MACHINE_ski
ski_kbd_grab();
#endif
#endif
}
 
/** Return console to userspace
*
*/
void arch_release_console(void)
{
#ifdef SKI
#ifdef MACHINE_ski
ski_kbd_release();
#endif
}
224,9 → 273,27
 
void arch_reboot(void)
{
// TODO
while (1);
pio_write_8((ioport8_t *)0x64, 0xfe);
while (1)
;
}
 
/** 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)
{
fptr->fnc = (unative_t) addr;
fptr->gp = ((unative_t *) caller)[1];
return (void *) fptr;
}
 
/** @}
*/
/branches/arm/kernel/arch/ia64/src/cpu/cpu.c
55,7 → 55,7
*((uint64_t *) &vendor[0 * sizeof(uint64_t)]) = CPU->arch.cpuid0;
*((uint64_t *) &vendor[1 * sizeof(uint64_t)]) = CPU->arch.cpuid1;
vendor[sizeof(vendor) - 1] = '\0';
vendor[sizeof(vendor) - 1] = 0;
switch(m->arch.cpuid3.family) {
case FAMILY_ITANIUM:
70,8 → 70,8
}
printf("cpu%d: %s (%s), archrev=%d, model=%d, revision=%d\n", CPU->id,
family_str, vendor, CPU->arch.cpuid3.archrev, CPU->arch.cpuid3.model,
CPU->arch.cpuid3.revision);
family_str, vendor, CPU->arch.cpuid3.archrev,
CPU->arch.cpuid3.model, CPU->arch.cpuid3.revision);
}
 
/** @}
/branches/arm/kernel/arch/ia64/src/interrupt.c
38,7 → 38,6
#include <ddi/irq.h>
#include <panic.h>
#include <print.h>
#include <symtab.h>
#include <debug.h>
#include <console/console.h>
#include <arch/types.h>
53,6 → 52,9
#include <ipc/irq.h>
#include <ipc/ipc.h>
#include <synch/spinlock.h>
#include <mm/tlb.h>
#include <symtab.h>
#include <putchar.h>
 
#define VECTORS_64_BUNDLE 20
#define VECTORS_16_BUNDLE 48
136,9 → 138,9
{
char *ifa, *iipa, *iip;
 
ifa = get_symtab_entry(istate->cr_ifa);
iipa = get_symtab_entry(istate->cr_iipa);
iip = get_symtab_entry(istate->cr_iip);
ifa = symtab_fmt_name_lookup(istate->cr_ifa);
iipa = symtab_fmt_name_lookup(istate->cr_iipa);
iip = symtab_fmt_name_lookup(istate->cr_iip);
 
putchar('\n');
printf("Interrupted context dump:\n");
185,21 → 187,21
break;
}
 
fault_if_from_uspace(istate, "General Exception (%s)", desc);
fault_if_from_uspace(istate, "General Exception (%s).", desc);
 
dump_interrupted_context(istate);
panic("General Exception (%s)\n", desc);
panic("General Exception (%s).", desc);
}
 
void disabled_fp_register(uint64_t vector, istate_t *istate)
{
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#ifdef CONFIG_FPU_LAZY
scheduler_fpu_lazy_request();
#else
fault_if_from_uspace(istate, "Interruption: %#hx (%s)",
fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
(uint16_t) vector, vector_to_string(vector));
dump_interrupted_context(istate);
panic("Interruption: %#hx (%s)\n", (uint16_t) vector,
panic("Interruption: %#hx (%s).", (uint16_t) vector,
vector_to_string(vector));
#endif
}
227,40 → 229,82
 
void universal_handler(uint64_t vector, istate_t *istate)
{
fault_if_from_uspace(istate, "Interruption: %#hx (%s)\n",
fault_if_from_uspace(istate, "Interruption: %#hx (%s).",
(uint16_t) vector, vector_to_string(vector));
dump_interrupted_context(istate);
panic("Interruption: %#hx (%s)\n", (uint16_t) vector,
panic("Interruption: %#hx (%s).", (uint16_t) vector,
vector_to_string(vector));
}
 
static void end_of_local_irq(void)
{
asm volatile ("mov cr.eoi=r0;;");
}
 
 
void external_interrupt(uint64_t vector, istate_t *istate)
{
cr_ivr_t ivr;
irq_t *irq;
cr_ivr_t ivr;
ivr.value = ivr_read();
srlz_d();
 
irq = irq_dispatch_and_lock(ivr.vector);
if (irq) {
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
switch (ivr.vector) {
case INTERRUPT_SPURIOUS:
switch (ivr.vector) {
case INTERRUPT_SPURIOUS:
#ifdef CONFIG_DEBUG
printf("cpu%d: spurious interrupt\n", CPU->id);
printf("cpu%d: spurious interrupt\n", CPU->id);
#endif
break;
break;
 
default:
panic("\nUnhandled External Interrupt Vector %d\n",
#ifdef CONFIG_SMP
case VECTOR_TLB_SHOOTDOWN_IPI:
tlb_shootdown_ipi_recv();
end_of_local_irq();
break;
#endif
 
case INTERRUPT_TIMER:
irq = irq_dispatch_and_lock(ivr.vector);
if (irq) {
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
panic("Unhandled Internal Timer Interrupt (%d).",
ivr.vector);
break;
}
break;
default:
irq = irq_dispatch_and_lock(ivr.vector);
if (irq) {
/*
* The IRQ handler was found.
*/
if (irq->preack) {
/* Send EOI before processing the interrupt */
end_of_local_irq();
}
irq->handler(irq);
if (!irq->preack)
end_of_local_irq();
spinlock_unlock(&irq->lock);
} else {
/*
* Unhandled interrupt.
*/
end_of_local_irq();
#ifdef CONFIG_DEBUG
printf("\nUnhandled External Interrupt Vector %d\n",
ivr.vector);
#endif
}
break;
}
}
 
void trap_virtual_enable_irqs(uint16_t irqmask)
{
}
 
/** @}
*/
/branches/arm/kernel/arch/ia64/src/asm.S
51,7 → 51,7
 
adds r14 = 7, in1
mov r2 = ar.lc
mov r8 = in0
mov r8 = in0 ;;
and r14 = -8, r14 ;;
cmp.ne p6, p7 = r14, in1
(p7) br.cond.dpnt 3f ;;
128,6 → 128,10
memsetb:
br _memsetb
 
.global memsetw
memsetw:
br _memsetw
 
.global cpu_halt
cpu_halt:
br cpu_halt
/branches/arm/kernel/arch/ia64/src/start.S
32,19 → 32,15
#include <mm/asid.h>
 
#define RR_MASK (0xFFFFFFFF00000002)
#define RID_SHIFT 8
#define PS_SHIFT 2
#define RID_SHIFT 8
#define PS_SHIFT 2
 
#define KERNEL_TRANSLATION_I 0x0010000000000661
#define KERNEL_TRANSLATION_D 0x0010000000000661
#define KERNEL_TRANSLATION_VIO 0x0010000000000671
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671
#define VIO_OFFSET 0x0002000000000000
#define KERNEL_TRANSLATION_I 0x0010000000000661
#define KERNEL_TRANSLATION_D 0x0010000000000661
#define KERNEL_TRANSLATION_VIO 0x0010000000000671
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671
#define KERNEL_TRANSLATION_FW 0x00100000F0000671
 
#define IO_OFFSET 0x0001000000000000
 
 
 
.section K_TEXT_START, "ax"
 
.global kernel_image_start
53,6 → 49,19
kernel_image_start:
.auto
 
#ifdef CONFIG_SMP
# Identify self(CPU) in OS structures by ID / EID
 
mov r9 = cr64
mov r10 = 1
movl r12 = 0xffffffff
movl r8 = cpu_by_id_eid_list
and r8 = r8, r12
shr r9 = r9, 16
add r8 = r8, r9
st1 [r8] = r10
#endif
 
mov psr.l = r0
srlz.i
srlz.d
59,39 → 68,29
 
# Fill TR.i and TR.d using Region Register #VRN_KERNEL
 
 
movl r8 = (VRN_KERNEL << VRN_SHIFT)
mov r9 = rr[r8]
 
 
movl r10 = (RR_MASK)
and r9 = r10, r9
movl r10 = ((RID_KERNEL << RID_SHIFT) | (KERNEL_PAGE_WIDTH << PS_SHIFT))
or r9 = r10, r9
 
 
mov rr[r8] = r9
 
 
 
movl r8 = (VRN_KERNEL << VRN_SHIFT)
mov cr.ifa = r8
 
mov r11 = cr.itir ;;
movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT);;
or r10 =r10 , r11 ;;
mov cr.itir = r10;;
mov r11 = cr.itir
movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT)
or r10 = r10, r11
mov cr.itir = r10
 
movl r10 = (KERNEL_TRANSLATION_I)
itr.i itr[r0] = r10
 
movl r10 = (KERNEL_TRANSLATION_D)
itr.d dtr[r0] = r10
 
 
movl r7 = 1
movl r8 = (VRN_KERNEL << VRN_SHIFT) | VIO_OFFSET
mov cr.ifa = r8
98,15 → 97,13
movl r10 = (KERNEL_TRANSLATION_VIO)
itr.d dtr[r7] = r10
 
mov r11 = cr.itir
movl r10 = ~0xfc
and r10 = r10, r11
movl r11 = (IO_PAGE_WIDTH << PS_SHIFT)
or r10 = r10, r11
mov cr.itir = r10
 
mov r11 = cr.itir ;;
movl r10 = ~0xfc;;
and r10 =r10 , r11 ;;
movl r11 = (IO_PAGE_WIDTH << PS_SHIFT);;
or r10 =r10 , r11 ;;
mov cr.itir = r10;;
 
 
movl r7 = 2
movl r8 = (VRN_KERNEL << VRN_SHIFT) | IO_OFFSET
mov cr.ifa = r8
113,12 → 110,26
movl r10 = (KERNEL_TRANSLATION_IO)
itr.d dtr[r7] = r10
 
# Setup mapping for fimware arrea (also SAPIC)
 
mov r11 = cr.itir
movl r10 = ~0xfc
and r10 = r10, r11
movl r11 = (FW_PAGE_WIDTH << PS_SHIFT)
or r10 = r10, r11
mov cr.itir = r10
 
movl r7 = 3
movl r8 = (VRN_KERNEL << VRN_SHIFT) | FW_OFFSET
mov cr.ifa = r8
movl r10 = (KERNEL_TRANSLATION_FW)
itr.d dtr[r7] = r10
 
# initialize PSR
# Initialize PSR
 
movl r10 = (PSR_DT_MASK | PSR_RT_MASK | PSR_IT_MASK | PSR_IC_MASK) /* Enable paging */
mov r9 = psr
 
or r10 = r10, r9
mov cr.ipsr = r10
mov cr.ifs = r0
128,11 → 139,14
srlz.i
 
.explicit
 
/*
* Return From Interupt is the only the way to fill upper half word of PSR.
* Return From Interrupt is the only way to
* fill the upper half word of PSR.
*/
rfi;;
rfi ;;
 
 
.global paging_start
paging_start:
 
140,45 → 154,64
* Now we are paging.
*/
 
# switch to register bank 1
# Switch to register bank 1
bsw.1
 
#ifdef CONFIG_SMP
# Am I BSP or AP?
movl r20 = bsp_started ;;
ld8 r20 = [r20] ;;
cmp.eq p3, p2 = r20, r0 ;;
#else
cmp.eq p3, p2 = r0, r0 ;; /* you are BSP */
#endif /* CONFIG_SMP */
# initialize register stack
# Initialize register stack
mov ar.rsc = r0
movl r8 = (VRN_KERNEL << VRN_SHIFT) ;;
mov ar.bspstore = r8
loadrs
 
# initialize memory stack to some sane value
# Initialize memory stack to some sane value
movl r12 = stack0 ;;
add r12 = -16, r12 /* allocate a scratch area on the stack */
 
# initialize gp (Global Pointer) register
# Initialize gp (Global Pointer) register
movl r20 = (VRN_KERNEL << VRN_SHIFT);;
or r20 = r20,r1;;
movl r1 = _hardcoded_load_address
/*
* Initialize hardcoded_* variables.
* Initialize hardcoded_* variables. Do only BSP
*/
movl r14 = _hardcoded_ktext_size
movl r15 = _hardcoded_kdata_size
movl r16 = _hardcoded_load_address ;;
addl r17 = @gprel(hardcoded_ktext_size), gp
addl r18 = @gprel(hardcoded_kdata_size), gp
addl r19 = @gprel(hardcoded_load_address), gp
addl r21 = @gprel(bootinfo), gp
(p3) movl r14 = _hardcoded_ktext_size
(p3) movl r15 = _hardcoded_kdata_size
(p3) movl r16 = _hardcoded_load_address ;;
(p3) addl r17 = @gprel(hardcoded_ktext_size), gp
(p3) addl r18 = @gprel(hardcoded_kdata_size), gp
(p3) addl r19 = @gprel(hardcoded_load_address), gp
(p3) addl r21 = @gprel(bootinfo), gp
;;
st8 [r17] = r14
st8 [r18] = r15
st8 [r19] = r16
st8 [r21] = r20
(p3) st8 [r17] = r14
(p3) st8 [r18] = r15
(p3) st8 [r19] = r16
(p3) st8 [r21] = r20
 
ssm (1 << 19) ;; /* Disable f32 - f127 */
srlz.i
srlz.d ;;
 
#ifdef CONFIG_SMP
(p2) movl r18 = main_ap ;;
(p2) mov b1 = r18 ;;
(p2) br.call.sptk.many b0 = b1
 
# Mark that BSP is on
mov r20 = 1 ;;
movl r21 = bsp_started ;;
st8 [r21] = r20 ;;
#endif
 
br.call.sptk.many b0 = arch_pre_main
 
movl r18 = main_bsp ;;
185,6 → 218,51
mov b1 = r18 ;;
br.call.sptk.many b0 = b1
 
 
0:
br 0b
 
#ifdef CONFIG_SMP
 
.align 4096
kernel_image_ap_start:
.auto
 
# Identify self(CPU) in OS structures by ID / EID
 
mov r9 = cr64
mov r10 = 1
movl r12 = 0xffffffff
movl r8 = cpu_by_id_eid_list
and r8 = r8, r12
shr r9 = r9, 16
add r8 = r8, r9
st1 [r8] = r10
# Wait for wakeup synchro signal (#3 in cpu_by_id_eid_list)
kernel_image_ap_start_loop:
movl r11 = kernel_image_ap_start_loop
and r11 = r11, r12
mov b1 = r11
 
ld1 r20 = [r8] ;;
movl r21 = 3 ;;
cmp.eq p2, p3 = r20, r21 ;;
(p3) br.call.sptk.many b0 = b1
 
movl r11 = kernel_image_start
and r11 = r11, r12
mov b1 = r11
br.call.sptk.many b0 = b1
 
.align 16
.global bsp_started
bsp_started:
.space 8
 
.align 4096
.global cpu_by_id_eid_list
cpu_by_id_eid_list:
.space 65536
 
#endif /* CONFIG_SMP */
/branches/arm/kernel/arch/ia64/src/fpu_context.c
149,8 → 149,10
"stf.spill [%7] = f127, 0x80\n;;"
 
:
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), "r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), "r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])),
"r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])),
"r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
);
}
267,14 → 269,16
"ldf.fill f127 = [%7], 0x80\n;;"
 
:
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), "r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), "r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])),
"r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])),
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])),
"r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7]))
);
}
 
void fpu_enable(void)
{
uint64_t a = 0 ;
uint64_t a = 0;
 
asm volatile (
"rsm %0 ;;"
/branches/arm/kernel/arch/ia64/src/ddi/ddi.c
1,5 → 1,6
/*
* Copyright (c) 2006 Jakub Jermar
* Copyright (c) 2008 Jakub vana
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
35,19 → 36,39
#include <ddi/ddi.h>
#include <proc/task.h>
#include <arch/types.h>
#include <mm/slab.h>
#include <errno.h>
 
#define IO_MEMMAP_PAGES 16384
#define PORTS_PER_PAGE 4
 
/** Enable I/O space range for task.
*
* Interrupts are disabled and task is locked.
*
* @param task Task.
* @param ioaddr Startign I/O space address.
* @param size Size of the enabled I/O range.
* @param task Task.
* @param ioaddr Starting I/O space address.
* @param size Size of the enabled I/O range.
*
* @return 0 on success or an error code from errno.h.
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
if (!task->arch.iomap) {
uint8_t *map;
 
task->arch.iomap = malloc(sizeof(bitmap_t), 0);
map = malloc(BITS2BYTES(IO_MEMMAP_PAGES), 0);
if(!map)
return ENOMEM;
bitmap_initialize(task->arch.iomap, map, IO_MEMMAP_PAGES);
bitmap_clear_range(task->arch.iomap, 0, IO_MEMMAP_PAGES);
}
uintptr_t iopage = ioaddr / PORTS_PER_PAGE;
size = ALIGN_UP(size + ioaddr - 4 * iopage, PORTS_PER_PAGE);
bitmap_set_range(task->arch.iomap, iopage, size / 4);
 
return 0;
}
 
/branches/arm/kernel/arch/ia64/src/proc/scheduler.c
47,14 → 47,17
{
}
 
/** Prepare kernel stack pointers in bank 0 r22 and r23 and make sure the stack is mapped in DTR. */
/** Prepare kernel stack pointers in bank 0 r22 and r23 and make sure the stack
* is mapped in DTR.
*/
void before_thread_runs_arch(void)
{
uintptr_t base;
base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH);
base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH);
 
if ((uintptr_t) THREAD->kstack < base || (uintptr_t) THREAD->kstack > base + (1<<(KERNEL_PAGE_WIDTH))) {
if ((uintptr_t) THREAD->kstack < base ||
(uintptr_t) THREAD->kstack > base + (1 << (KERNEL_PAGE_WIDTH))) {
/*
* Kernel stack of this thread is not mapped by DTR[TR_KERNEL].
* Use DTR[TR_KSTACK1] and DTR[TR_KSTACK2] to map it.
64,8 → 67,11
dtr_purge((uintptr_t) THREAD->kstack, PAGE_WIDTH+1);
/* insert DTR[TR_STACK1] and DTR[TR_STACK2] */
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack, KA2PA(THREAD->kstack), true, DTR_KSTACK1);
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack + PAGE_SIZE, KA2PA(THREAD->kstack) + FRAME_SIZE, true, DTR_KSTACK2);
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack,
KA2PA(THREAD->kstack), true, DTR_KSTACK1);
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack +
PAGE_SIZE, KA2PA(THREAD->kstack) + FRAME_SIZE, true,
DTR_KSTACK2);
}
/*
/branches/arm/kernel/arch/ia64/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf64-little
BFD_ARCH = ia64-elf64
TARGET = ia64-pc-linux-gnu
45,56 → 41,35
LFLAGS += -EL
AFLAGS += -mconstant-gp
 
DEFS += -D__64_BITS__ -D$(MACHINE)
BITS = 64
ENDIANESS = LE
 
## Compile with page hash table support.
#
 
CONFIG_PAGE_HT = y
DEFS += -DCONFIG_PAGE_HT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/ia64.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/ivt.S \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/mm/vhpt.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/it.c
arch/$(KARCH)/src/start.S \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/dummy.s \
arch/$(KARCH)/src/ia64.c \
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/ivt.S \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/mm/vhpt.c \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/smp/smp.c \
arch/$(KARCH)/src/drivers/it.c
 
ifeq ($(MACHINE),ski)
ARCH_SOURCES += arch/$(ARCH)/src/ski/ski.c
DEFS += -DSKI
# BFD = elf64-ia64-little
ARCH_SOURCES += arch/$(KARCH)/src/drivers/ski.c
BFD = binary
endif
 
ifeq ($(MACHINE),i460GX)
ARCH_SOURCES += arch/$(ARCH)/src/drivers/ega.c
CONFIG_I8042 = y
DEFS += -DI460GX -DCONFIG_I8042
DEFS += -DI460GX
BFD = binary
endif
 
/branches/arm/kernel/arch/ppc32/src/ppc32.c
35,7 → 35,8
#include <config.h>
#include <arch.h>
#include <arch/boot/boot.h>
#include <arch/drivers/cuda.h>
#include <genarch/drivers/via-cuda/cuda.h>
#include <genarch/kbrd/kbrd.h>
#include <arch/interrupt.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
42,24 → 43,29
#include <userspace.h>
#include <proc/uarg.h>
#include <console/console.h>
#include <ddi/device.h>
#include <ddi/irq.h>
#include <arch/drivers/pic.h>
#include <align.h>
#include <macros.h>
#include <string.h>
 
#define IRQ_COUNT 64
#define IRQ_COUNT 64
#define IRQ_CUDA 10
 
bootinfo_t bootinfo;
 
/** Performs ppc32-specific initialization before main_bsp() is called. */
void arch_pre_main(void)
{
/* Setup usermode */
init.cnt = bootinfo.taskmap.count;
uint32_t i;
for (i = 0; i < bootinfo.taskmap.count; i++) {
for (i = 0; i < min3(bootinfo.taskmap.count, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) {
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr);
init.tasks[i].size = bootinfo.taskmap.tasks[i].size;
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
bootinfo.taskmap.tasks[i].name);
}
}
 
75,36 → 81,43
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
 
#ifdef CONFIG_FB
/* Initialize framebuffer */
unsigned int visual;
switch (bootinfo.screen.bpp) {
case 8:
visual = VISUAL_INDIRECT_8;
break;
case 16:
visual = VISUAL_RGB_5_5_5;
break;
case 24:
visual = VISUAL_RGB_8_8_8;
break;
case 32:
visual = VISUAL_RGB_0_8_8_8;
break;
default:
panic("Unsupported bits per pixel");
if (bootinfo.screen.addr) {
unsigned int visual;
switch (bootinfo.screen.bpp) {
case 8:
visual = VISUAL_INDIRECT_8;
break;
case 16:
visual = VISUAL_RGB_5_5_5;
break;
case 24:
visual = VISUAL_RGB_8_8_8;
break;
case 32:
visual = VISUAL_RGB_0_8_8_8;
break;
default:
panic("Unsupported bits per pixel.");
}
fb_properties_t prop = {
.addr = bootinfo.screen.addr,
.offset = 0,
.x = bootinfo.screen.width,
.y = bootinfo.screen.height,
.scan = bootinfo.screen.scanline,
.visual = visual,
};
fb_init(&prop);
}
fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.scanline, visual);
#endif
/* Initialize IRQ routing */
irq_init(IRQ_COUNT, IRQ_COUNT);
/* Initialize PIC */
pic_init(bootinfo.keyboard.addr, PAGE_SIZE);
/* Initialize I/O controller */
cuda_init(device_assign_devno(), bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE);
/* Merge all zones to 1 big zone */
zone_merge_all();
}
120,6 → 133,35
 
void arch_post_smp_init(void)
{
if (bootinfo.macio.addr) {
/* Initialize PIC */
cir_t cir;
void *cir_arg;
pic_init(bootinfo.macio.addr, PAGE_SIZE, &cir, &cir_arg);
 
#ifdef CONFIG_MAC_KBD
uintptr_t pa = bootinfo.macio.addr + 0x16000;
uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE);
size_t offset = pa - aligned_addr;
size_t size = 2 * PAGE_SIZE;
cuda_t *cuda = (cuda_t *)
(hw_map(aligned_addr, offset + size) + offset);
/* Initialize I/O controller */
cuda_instance_t *cuda_instance =
cuda_init(cuda, IRQ_CUDA, cir, cir_arg);
if (cuda_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
cuda_wire(cuda_instance, kbrd);
pic_enable_interrupt(IRQ_CUDA);
}
}
#endif
}
}
 
void calibrate_delay_loop(void)
128,11 → 170,13
 
void userspace(uspace_arg_t *kernel_uarg)
{
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg, (uintptr_t) kernel_uarg->uspace_stack + THREAD_STACK_SIZE - SP_DELTA, (uintptr_t) kernel_uarg->uspace_entry);
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg,
(uintptr_t) kernel_uarg->uspace_stack +
THREAD_STACK_SIZE - SP_DELTA,
(uintptr_t) kernel_uarg->uspace_entry);
/* Unreachable */
for (;;)
;
while (true);
}
 
/** Acquire console back for kernel
140,7 → 184,9
*/
void arch_grab_console(void)
{
cuda_grab();
#ifdef CONFIG_FB
fb_redraw();
#endif
}
 
/** Return console to userspace
148,8 → 194,27
*/
void arch_release_console(void)
{
cuda_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;
}
 
void arch_reboot(void)
{
// TODO
while (1);
}
 
/** @}
*/
/branches/arm/kernel/arch/ppc32/src/mm/tlb.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32mm
/** @addtogroup ppc32mm
* @{
*/
/** @file
35,12 → 35,22
#include <mm/tlb.h>
#include <arch/mm/tlb.h>
#include <arch/interrupt.h>
#include <interrupt.h>
#include <mm/as.h>
#include <arch.h>
#include <print.h>
#include <macros.h>
#include <symtab.h>
 
static unsigned int seed = 10;
static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
 
 
#define TLB_FLUSH \
"tlbie %0\n" \
"addi %0, %0, 0x1000\n"
 
 
/** Try to find PTE for faulting address
*
* Try to find PTE for faulting address.
65,7 → 75,7
* Check if the mapping exists in page tables.
*/
pte_t *pte = page_mapping_find(as, badvaddr);
if ((pte) && (pte->p)) {
if ((pte) && (pte->present)) {
/*
* Mapping found in page tables.
* Immediately succeed.
87,7 → 97,7
*/
page_table_lock(as, lock);
pte = page_mapping_find(as, badvaddr);
ASSERT((pte) && (pte->p));
ASSERT((pte) && (pte->present));
*pfrc = 0;
return pte;
case AS_PF_DEFER:
96,11 → 106,10
return NULL;
case AS_PF_FAULT:
page_table_lock(as, lock);
printf("Page fault.\n");
*pfrc = rc;
return NULL;
default:
panic("unexpected rc (%d)\n", rc);
panic("Unexpected rc (%d).", rc);
}
}
}
108,21 → 117,20
 
static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
{
char *symbol = "";
char *sym2 = "";
char *symbol;
char *sym2;
 
char *s = get_symtab_entry(istate->pc);
if (s)
symbol = s;
s = get_symtab_entry(istate->lr);
if (s)
sym2 = s;
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr,
symbol = symtab_fmt_name_lookup(istate->pc);
sym2 = symtab_fmt_name_lookup(istate->lr);
 
fault_if_from_uspace(istate,
"PHT Refill Exception on %p.", badvaddr);
panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr,
istate->pc, symbol, sym2);
}
 
 
static void pht_insert(const uintptr_t vaddr, const pfn_t pfn)
static void pht_insert(const uintptr_t vaddr, const pte_t *pte)
{
uint32_t page = (vaddr >> 12) & 0xffff;
uint32_t api = (vaddr >> 22) & 0x3f;
148,11 → 156,12
uint32_t i;
bool found = false;
/* Find unused or colliding
PTE in PTEG */
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) &&
(phte[base + i].api == api))) {
if ((phte[base + i].v)
&& (phte[base + i].vsid == vsid)
&& (phte[base + i].api == api)
&& (phte[base + i].h == 0)) {
found = true;
break;
}
159,86 → 168,25
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find unused or colliding
PTE in PTEG */
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte[base2 + i].v) ||
((phte[base2 + i].vsid == vsid) &&
(phte[base2 + i].api == api))) {
if (!phte[base + i].v) {
found = true;
base = base2;
h = 1;
break;
}
}
if (!found) {
// TODO: A/C precedence groups
i = page % 8;
}
}
phte[base + i].v = 1;
phte[base + i].vsid = vsid;
phte[base + i].h = h;
phte[base + i].api = api;
phte[base + i].rpn = pfn;
phte[base + i].r = 0;
phte[base + i].c = 0;
phte[base + i].pp = 2; // FIXME
}
 
 
static void pht_real_insert(const uintptr_t vaddr, const pfn_t pfn)
{
uint32_t page = (vaddr >> 12) & 0xffff;
uint32_t api = (vaddr >> 22) & 0x3f;
uint32_t vsid;
asm volatile (
"mfsrin %0, %1\n"
: "=r" (vsid)
: "r" (vaddr)
);
uint32_t sdr1;
asm volatile (
"mfsdr1 %0\n"
: "=r" (sdr1)
);
phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000);
/* Primary hash (xor) */
uint32_t h = 0;
uint32_t hash = vsid ^ page;
uint32_t base = (hash & 0x3ff) << 3;
uint32_t i;
bool found = false;
/* Find unused or colliding
PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte_physical[base + i].v) ||
((phte_physical[base + i].vsid == vsid) &&
(phte_physical[base + i].api == api))) {
found = true;
break;
}
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find unused or colliding
PTE in PTEG */
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((!phte_physical[base2 + i].v) ||
((phte_physical[base2 + i].vsid == vsid) &&
(phte_physical[base2 + i].api == api))) {
if ((phte[base2 + i].v)
&& (phte[base2 + i].vsid == vsid)
&& (phte[base2 + i].api == api)
&& (phte[base2 + i].h == 1)) {
found = true;
base = base2;
h = 1;
247,26 → 195,37
}
if (!found) {
// TODO: A/C precedence groups
i = page % 8;
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if (!phte[base2 + i].v) {
found = true;
base = base2;
h = 1;
break;
}
}
}
if (!found)
i = RANDI(seed) % 8;
}
phte_physical[base + i].v = 1;
phte_physical[base + i].vsid = vsid;
phte_physical[base + i].h = h;
phte_physical[base + i].api = api;
phte_physical[base + i].rpn = pfn;
phte_physical[base + i].r = 0;
phte_physical[base + i].c = 0;
phte_physical[base + i].pp = 2; // FIXME
phte[base + i].v = 1;
phte[base + i].vsid = vsid;
phte[base + i].h = h;
phte[base + i].api = api;
phte[base + i].rpn = pte->pfn;
phte[base + i].r = 0;
phte[base + i].c = 0;
phte[base + i].wimg = (pte->page_cache_disable ? WIMG_NO_CACHE : 0);
phte[base + i].pp = 2; // FIXME
}
 
 
/** Process Instruction/Data Storage Interrupt
/** Process Instruction/Data Storage Exception
*
* @param n Interrupt vector number.
* @param istate Interrupted register context.
* @param n Exception vector number.
* @param istate Interrupted register context.
*
*/
void pht_refill(int n, istate_t *istate)
285,12 → 244,9
lock = true;
}
if (n == VECTOR_DATA_STORAGE) {
asm volatile (
"mfdar %0\n"
: "=r" (badvaddr)
);
} else
if (n == VECTOR_DATA_STORAGE)
badvaddr = istate->dar;
else
badvaddr = istate->pc;
page_table_lock(as, lock);
310,12 → 266,12
page_table_unlock(as, lock);
return;
default:
panic("Unexpected pfrc (%d)\n", pfrc);
panic("Unexpected pfrc (%d).", pfrc);
}
}
pte->a = 1; /* Record access to PTE */
pht_insert(badvaddr, pte->pfn);
pte->accessed = 1; /* Record access to PTE */
pht_insert(badvaddr, pte);
page_table_unlock(as, lock);
return;
326,22 → 282,19
}
 
 
/** Process Instruction/Data Storage Interrupt in Real Mode
/** Process Instruction/Data Storage Exception in Real Mode
*
* @param n Interrupt vector number.
* @param istate Interrupted register context.
* @param n Exception vector number.
* @param istate Interrupted register context.
*
*/
bool pht_real_refill(int n, istate_t *istate)
bool pht_refill_real(int n, istate_t *istate)
{
uintptr_t badvaddr;
if (n == VECTOR_DATA_STORAGE) {
asm volatile (
"mfdar %0\n"
: "=r" (badvaddr)
);
} else
if (n == VECTOR_DATA_STORAGE)
badvaddr = istate->dar;
else
badvaddr = istate->pc;
uint32_t physmem;
350,15 → 303,140
: "=r" (physmem)
);
if ((badvaddr >= PA2KA(0)) && (badvaddr < PA2KA(physmem))) {
pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12);
return true;
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
return false;
uint32_t page = (badvaddr >> 12) & 0xffff;
uint32_t api = (badvaddr >> 22) & 0x3f;
uint32_t vsid;
asm volatile (
"mfsrin %0, %1\n"
: "=r" (vsid)
: "r" (badvaddr)
);
uint32_t sdr1;
asm volatile (
"mfsdr1 %0\n"
: "=r" (sdr1)
);
phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000);
/* Primary hash (xor) */
uint32_t h = 0;
uint32_t hash = vsid ^ page;
uint32_t base = (hash & 0x3ff) << 3;
uint32_t i;
bool found = false;
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((phte_real[base + i].v)
&& (phte_real[base + i].vsid == vsid)
&& (phte_real[base + i].api == api)
&& (phte_real[base + i].h == 0)) {
found = true;
break;
}
}
return false;
if (!found) {
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if (!phte_real[base + i].v) {
found = true;
break;
}
}
}
if (!found) {
/* Secondary hash (not) */
uint32_t base2 = (~hash & 0x3ff) << 3;
/* Find colliding PTE in PTEG */
for (i = 0; i < 8; i++) {
if ((phte_real[base2 + i].v)
&& (phte_real[base2 + i].vsid == vsid)
&& (phte_real[base2 + i].api == api)
&& (phte_real[base2 + i].h == 1)) {
found = true;
base = base2;
h = 1;
break;
}
}
if (!found) {
/* Find unused PTE in PTEG */
for (i = 0; i < 8; i++) {
if (!phte_real[base2 + i].v) {
found = true;
base = base2;
h = 1;
break;
}
}
}
if (!found) {
/* Use secondary hash to avoid collisions
with usual PHT refill handler. */
i = RANDI(seed_real) % 8;
base = base2;
h = 1;
}
}
phte_real[base + i].v = 1;
phte_real[base + i].vsid = vsid;
phte_real[base + i].h = h;
phte_real[base + i].api = api;
phte_real[base + i].rpn = KA2PA(badvaddr) >> 12;
phte_real[base + i].r = 0;
phte_real[base + i].c = 0;
phte_real[base + i].wimg = 0;
phte_real[base + i].pp = 2; // FIXME
return true;
}
 
 
/** Process ITLB/DTLB Miss Exception in Real Mode
*
*
*/
void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate)
{
uint32_t badvaddr = tlbmiss & 0xfffffffc;
uint32_t physmem;
asm volatile (
"mfsprg3 %0\n"
: "=r" (physmem)
);
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem)))
return; // FIXME
ptelo.rpn = KA2PA(badvaddr) >> 12;
ptelo.wimg = 0;
ptelo.pp = 2; // FIXME
uint32_t index = 0;
asm volatile (
"mtspr 981, %0\n"
"mtspr 982, %1\n"
"tlbld %2\n"
"tlbli %2\n"
: "=r" (index)
: "r" (ptehi),
"r" (ptelo)
);
}
 
 
void tlb_arch_init(void)
{
tlb_invalidate_all();
367,9 → 445,87
 
void tlb_invalidate_all(void)
{
uint32_t index;
asm volatile (
"tlbia\n"
"li %0, 0\n"
"sync\n"
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
TLB_FLUSH
"eieio\n"
"tlbsync\n"
"sync\n"
: "=r" (index)
);
}
 
393,7 → 549,7
}
 
 
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt)
{
// TODO
tlb_invalidate_all();
438,7 → 594,7
: "=r" (vsid)
: "r" (sr << 28)
);
printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr,
printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr,
sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4,
((vsid >> 30) & 1) ? " supervisor" : "",
((vsid >> 29) & 1) ? " user" : "");
/branches/arm/kernel/arch/ppc32/src/mm/frame.c
57,7 → 57,7
void frame_arch_init(void)
{
pfn_t minconf = 2;
count_t i;
size_t i;
pfn_t start, conf;
size_t size;
74,7 → 74,7
if (last_frame < ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE))
last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE);
}
 
/* First is exception vector, second is 'implementation specific',
third and fourth is reserved, other contain real mode code */
frame_mark_unavailable(0, 8);
/branches/arm/kernel/arch/ppc32/src/mm/page.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32mm
/** @addtogroup ppc32mm
* @{
*/
/** @file
49,7 → 49,7
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) >
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
panic("Unable to map physical memory %p (%" PRIs " bytes)",
panic("Unable to map physical memory %p (%" PRIs " bytes).",
physaddr, size)
uintptr_t virtaddr = PA2KA(last_frame);
/branches/arm/kernel/arch/ppc32/src/dummy.s
30,6 → 30,7
 
.global asm_delay_loop
.global sys_tls_set
.global cpu_halt
 
sys_tls_set:
b sys_tls_set
36,3 → 37,6
 
asm_delay_loop:
blr
 
cpu_halt:
b cpu_halt
/branches/arm/kernel/arch/ppc32/src/interrupt.c
60,7 → 60,6
int inum;
while ((inum = pic_get_pending()) != -1) {
bool ack = false;
irq_t *irq = irq_dispatch_and_lock(inum);
if (irq) {
/*
69,11 → 68,17
if (irq->preack) {
/* Acknowledge the interrupt before processing */
pic_ack_interrupt(inum);
ack = true;
if (irq->cir)
irq->cir(irq->cir_arg, irq->inr);
}
irq->handler(irq, irq->arg);
irq->handler(irq);
if (!irq->preack) {
if (irq->cir)
irq->cir(irq->cir_arg, irq->inr);
}
spinlock_unlock(&irq->lock);
} else {
/*
83,9 → 88,6
printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, inum);
#endif
}
if (!ack)
pic_ack_interrupt(inum);
}
}
 
92,8 → 94,8
 
static void exception_decrementer(int n, istate_t *istate)
{
start_decrementer();
clock();
start_decrementer();
}
 
 
/branches/arm/kernel/arch/ppc32/src/drivers/cuda.c
File deleted
/branches/arm/kernel/arch/ppc32/src/drivers/pic.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
38,53 → 38,61
#include <byteorder.h>
#include <bitops.h>
 
static volatile uint32_t *pic;
static volatile uint32_t *pic = NULL;
 
void pic_init(uintptr_t base, size_t size)
void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg)
{
pic = (uint32_t *) hw_map(base, size);
*cir = pic_ack_interrupt;
*cir_arg = NULL;
}
 
void pic_enable_interrupt(int intnum)
void pic_enable_interrupt(inr_t intnum)
{
if (intnum < 32) {
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum);
} else {
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32));
if (pic) {
if (intnum < 32)
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum);
else
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32));
}
}
 
void pic_disable_interrupt(int intnum)
void pic_disable_interrupt(inr_t intnum)
{
if (intnum < 32) {
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum));
} else {
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32)));
if (pic) {
if (intnum < 32)
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum));
else
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32)));
}
}
 
void pic_ack_interrupt(int intnum)
void pic_ack_interrupt(void *arg, inr_t intnum)
{
if (intnum < 32)
pic[PIC_ACK_LOW] = 1 << intnum;
else
pic[PIC_ACK_HIGH] = 1 << (intnum - 32);
if (pic) {
if (intnum < 32)
pic[PIC_ACK_LOW] = 1 << intnum;
else
pic[PIC_ACK_HIGH] = 1 << (intnum - 32);
}
}
 
/** Return number of pending interrupt */
int pic_get_pending(void)
{
int pending;
 
pending = pic[PIC_PENDING_LOW];
if (pending)
return fnzb32(pending);
if (pic) {
int pending;
pending = pic[PIC_PENDING_LOW];
if (pending)
return fnzb32(pending);
pending = pic[PIC_PENDING_HIGH];
if (pending)
return fnzb32(pending) + 32;
}
pending = pic[PIC_PENDING_HIGH];
if (pending)
return fnzb32(pending) + 32;
return -1;
}
 
/branches/arm/kernel/arch/ppc32/src/asm.S
34,6 → 34,7
.global iret
.global iret_syscall
.global memsetb
.global memsetw
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
66,9 → 67,9
mr sp, r4
 
# %r3 is defined to hold pcb_ptr - set it to 0
# %r6 is defined to hold pcb_ptr - set it to 0
 
xor r3, r3, r3
xor r6, r6, r6
# jump to userspace
131,8 → 132,8
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
lwz r12, 156(sp)
lwz sp, 160(sp)
rfi
 
197,14 → 198,17
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
lwz r12, 156(sp)
lwz sp, 160(sp)
 
rfi
 
memsetb:
b _memsetb
 
memsetw:
b _memsetw
 
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
/branches/arm/kernel/arch/ppc32/src/boot/boot.S
33,7 → 33,7
 
.global kernel_image_start
kernel_image_start:
 
# load temporal kernel stack
lis sp, kernel_stack@ha
52,7 → 52,7
beq bootinfo_end
addis r3, r3, 0x8000
 
lis r31, bootinfo@ha
addi r31, r31, bootinfo@l # r31 = bootinfo
/branches/arm/kernel/arch/ppc32/src/exception.S
60,7 → 60,7
2:
subi sp, sp, 160
subi sp, sp, 164
stw r0, 8(sp)
stw r2, 12(sp)
stw r3, 16(sp)
109,11 → 109,14
mfxer r12
stw r12, 148(sp)
mfsprg1 r12
mfdar r12
stw r12, 152(sp)
mfsprg1 r12
stw r12, 156(sp)
mfsprg2 r12
stw r12, 156(sp)
stw r12, 160(sp)
.endm
 
.org 0x100
137,16 → 140,7
exc_data_storage:
CONTEXT_STORE
li r3, 2
mr r4, sp
addi r4, r4, 8
bl pht_real_refill
cmpwi r3, 0
bne iret_real
li r3, 2
b jump_to_kernel
b data_storage
 
.org 0x400
.global exc_instruction_storage
153,17 → 147,8
exc_instruction_storage:
CONTEXT_STORE
li r3, 3
mr r4, sp
addi r4, r4, 8
bl pht_real_refill
cmpwi r3, 0
bne iret_real
b instruction_storage
 
li r3, 3
b jump_to_kernel
 
.org 0x500
.global exc_external
exc_external:
223,7 → 208,7
.org 0xc00
.global exc_syscall
exc_syscall:
CONTEXT_STORE
CONTEXT_STORE
b jump_to_kernel_syscall
 
235,7 → 220,63
li r3, 12
b jump_to_kernel
 
.org 0x1000
.global exc_itlb_miss
exc_itlb_miss:
CONTEXT_STORE
b tlb_miss
 
.org 0x1100
.global exc_dtlb_miss_load
exc_dtlb_miss_load:
CONTEXT_STORE
b tlb_miss
 
.org 0x1200
.global exc_dtlb_miss_store
exc_dtlb_miss_store:
CONTEXT_STORE
b tlb_miss
 
.org 0x4000
data_storage:
li r3, 2
mr r4, sp
addi r4, r4, 8
bl pht_refill_real
cmpwi r3, 0
bne iret_real
li r3, 2
b jump_to_kernel
 
instruction_storage:
li r3, 3
mr r4, sp
addi r4, r4, 8
bl pht_refill_real
cmpwi r3, 0
bne iret_real
li r3, 3
b jump_to_kernel
 
tlb_miss:
li r3, 16
mfspr r4, tlbmiss
mfspr r5, ptehi
mfspr r6, ptelo
mr r7, sp
addi r7, r7, 20
bl tlb_refill_real
b iret_real
 
jump_to_kernel:
lis r12, iret@ha
addi r12, r12, iret@l
272,7 → 313,6
rfi
 
iret_real:
lwz r0, 8(sp)
lwz r2, 12(sp)
lwz r3, 16(sp)
322,7 → 362,7
lwz r12, 148(sp)
mtxer r12
lwz r12, 152(sp)
lwz sp, 156(sp)
lwz r12, 156(sp)
lwz sp, 160(sp)
rfi
/branches/arm/kernel/arch/ppc32/include/byteorder.h
File deleted
/branches/arm/kernel/arch/ppc32/include/types.h
46,8 → 46,6
typedef unsigned long long uint64_t;
 
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
typedef uint32_t pfn_t;
57,11 → 55,12
typedef uint32_t unative_t;
typedef int32_t native_t;
 
/**< Formats for uintptr_t, size_t, count_t and index_t */
typedef struct {
} fncptr_t;
 
/**< Formats for uintptr_t, size_t */
#define PRIp "x"
#define PRIs "u"
#define PRIc "u"
#define PRIi "u"
 
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
#define PRId8 "d"
84,11 → 83,13
 
/** Page Table Entry. */
typedef struct {
unsigned p : 1; /**< Present bit. */
unsigned a : 1; /**< Accessed bit. */
unsigned g : 1; /**< Global bit. */
unsigned valid : 1; /**< Valid content even if not present. */
unsigned pfn : 20; /**< Physical frame number. */
unsigned present : 1; /**< Present bit. */
unsigned page_write_through : 1; /**< Write thought caching. */
unsigned page_cache_disable : 1; /**< No caching. */
unsigned accessed : 1; /**< Accessed bit. */
unsigned global : 1; /**< Global bit. */
unsigned valid : 1; /**< Valid content even if not present. */
unsigned pfn : 20; /**< Physical frame number. */
} pte_t;
 
#endif
/branches/arm/kernel/arch/ppc32/include/mm/page.h
102,25 → 102,25
 
/* Get PTE flags accessors for each level. */
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
get_pt_flags((pte_t *) (ptl0), (index_t) (i))
get_pt_flags((pte_t *) (ptl0), (size_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
get_pt_flags((pte_t *) (ptl3), (index_t) (i))
get_pt_flags((pte_t *) (ptl3), (size_t) (i))
 
/* Set PTE flags accessors for each level. */
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
 
/* Macros for querying the last-level PTEs. */
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0)
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0)
#define PTE_PRESENT_ARCH(pte) ((pte)->present != 0)
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn << 12)
#define PTE_WRITABLE_ARCH(pte) 1
#define PTE_EXECUTABLE_ARCH(pte) 1
130,25 → 130,26
#include <mm/mm.h>
#include <arch/interrupt.h>
 
static inline int get_pt_flags(pte_t *pt, index_t i)
static inline int get_pt_flags(pte_t *pt, size_t i)
{
pte_t *p = &pt[i];
return ((1 << PAGE_CACHEABLE_SHIFT) |
((!p->p) << PAGE_PRESENT_SHIFT) |
return (((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT) |
((!p->present) << PAGE_PRESENT_SHIFT) |
(1 << PAGE_USER_SHIFT) |
(1 << PAGE_READ_SHIFT) |
(1 << PAGE_WRITE_SHIFT) |
(1 << PAGE_EXEC_SHIFT) |
(p->g << PAGE_GLOBAL_SHIFT));
(p->global << PAGE_GLOBAL_SHIFT));
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
{
pte_t *p = &pt[i];
p->p = !(flags & PAGE_NOT_PRESENT);
p->g = (flags & PAGE_GLOBAL) != 0;
p->page_cache_disable = !(flags & PAGE_CACHEABLE);
p->present = !(flags & PAGE_NOT_PRESENT);
p->global = (flags & PAGE_GLOBAL) != 0;
p->valid = 1;
}
 
/branches/arm/kernel/arch/ppc32/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32mm
/** @addtogroup ppc32mm
* @{
*/
/** @file
35,13 → 35,13
#ifndef KERN_ppc32_FRAME_H_
#define KERN_ppc32_FRAME_H_
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
#include <arch/types.h>
 
extern uintptr_t last_frame;
 
/branches/arm/kernel/arch/ppc32/include/mm/tlb.h
39,6 → 39,11
#include <arch/types.h>
#include <typedefs.h>
 
#define WIMG_GUARDED 0x01
#define WIMG_COHERENT 0x02
#define WIMG_NO_CACHE 0x04
#define WIMG_WRITETHRU 0x08
 
typedef struct {
unsigned v : 1; /**< Valid */
unsigned vsid : 24; /**< Virtual Segment ID */
53,9 → 58,27
unsigned pp : 2; /**< Page protection */
} phte_t;
 
typedef struct {
unsigned v : 1;
unsigned vsid : 24;
unsigned reserved0 : 1;
unsigned api : 6;
} ptehi_t;
 
typedef struct {
unsigned rpn : 20;
unsigned xpn : 3;
unsigned reserved0 : 1;
unsigned c : 1;
unsigned wimg : 4;
unsigned x : 1;
unsigned pp : 2;
} ptelo_t;
 
extern void pht_init(void);
extern void pht_refill(int n, istate_t *istate);
extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
extern void pht_init(void);
extern bool pht_refill_real(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
extern void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START")));
 
#endif
 
/branches/arm/kernel/arch/ppc32/include/drivers/cuda.h
File deleted
/branches/arm/kernel/arch/ppc32/include/drivers/pic.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
36,6 → 36,7
#define KERN_ppc32_PIC_H_
 
#include <arch/types.h>
#include <ddi/irq.h>
 
#define PIC_PENDING_LOW 8
#define PIC_PENDING_HIGH 4
44,11 → 45,11
#define PIC_ACK_LOW 10
#define PIC_ACK_HIGH 6
 
void pic_init(uintptr_t base, size_t size);
void pic_enable_interrupt(int intnum);
void pic_disable_interrupt(int intnum);
void pic_ack_interrupt(int intnum);
int pic_get_pending(void);
extern void pic_init(uintptr_t base, size_t size, cir_t *cir, void **cir_arg);
extern void pic_enable_interrupt(inr_t intnum);
extern void pic_disable_interrupt(inr_t intnum);
extern void pic_ack_interrupt(void *arg, inr_t intnum);
extern int pic_get_pending(void);
 
#endif
 
/branches/arm/kernel/arch/ppc32/include/boot/boot.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
35,21 → 35,24
#ifndef KERN_ppc32_BOOT_H_
#define KERN_ppc32_BOOT_H_
 
#define BOOT_OFFSET 0x8000
#define BOOT_OFFSET 0x8000
 
/* Temporary stack size for boot process */
#define TEMP_STACK_SIZE 0x1000
#define TEMP_STACK_SIZE 0x1000
 
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
#define TASKMAP_MAX_RECORDS 32
#define MEMMAP_MAX_RECORDS 32
 
#ifndef __ASM__
 
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
#include <arch/types.h>
 
typedef struct {
uintptr_t addr;
uint32_t size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} utask_t;
 
typedef struct {
79,13 → 82,13
typedef struct {
uintptr_t addr;
unsigned int size;
} keyboard_t;
} macio_t;
 
typedef struct {
memmap_t memmap;
taskmap_t taskmap;
screen_t screen;
keyboard_t keyboard;
macio_t macio;
} bootinfo_t;
 
extern bootinfo_t bootinfo;
/branches/arm/kernel/arch/ppc32/include/asm.h
36,6 → 36,7
#define KERN_ppc32_ASM_H_
 
#include <arch/types.h>
#include <typedefs.h>
#include <config.h>
 
/** Enable interrupts.
149,6 → 150,36
 
extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry);
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
return *port;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
return *port;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
return *port;
}
 
#endif
 
/** @}
/branches/arm/kernel/arch/ppc32/include/arch.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
35,7 → 35,7
#ifndef KERN_ppc32_ARCH_H_
#define KERN_ppc32_ARCH_H_
 
#include <arch/drivers/cuda.h>
extern void arch_pre_main(void);
 
#endif
 
/branches/arm/kernel/arch/ppc32/include/asm/regname.h
211,6 → 211,9
#define dbat2l 541
#define dbat3u 542
#define dbat3l 543
#define tlbmiss 980
#define ptehi 981
#define ptelo 982
#define hid0 1008
 
/* MSR bits */
220,6 → 223,7
#define msr_ee (1 << 15)
 
/* HID0 bits */
#define hid0_sten (1 << 24)
#define hid0_ice (1 << 15)
#define hid0_dce (1 << 14)
#define hid0_icfi (1 << 11)
/branches/arm/kernel/arch/ppc32/include/barrier.h
55,6 → 55,7
"dcbst 0, %0\n"
"sync\n"
"icbi 0, %0\n"
"sync\n"
"isync\n"
:: "r" (addr)
);
76,7 → 77,10
asm volatile ("icbi 0, %0\n" :: "r" (addr + i));
}
 
asm volatile ("isync");
asm volatile (
"sync\n"
"isync\n"
);
}
 
#endif
/branches/arm/kernel/arch/ppc32/include/exception.h
75,6 → 75,7
uint32_t lr;
uint32_t ctr;
uint32_t xer;
uint32_t dar;
uint32_t r12;
uint32_t sp;
} istate_t;
/branches/arm/kernel/arch/ppc32/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf32-powerpc
BFD_ARCH = powerpc:common
BFD = binary
43,46 → 39,24
AFLAGS += -a32
LFLAGS += -no-check-sections -N
 
DEFS += -D__32_BITS__
BITS = 32
ENDIANESS = BE
 
## Own configuration directives
#
 
CONFIG_FB = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with support for address space identifiers.
#
 
CONFIG_ASID = y
CONFIG_ASID_FIFO = y
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/debug/panic.s \
arch/$(ARCH)/src/fpu_context.S \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/ppc32.c \
arch/$(ARCH)/src/dummy.s \
arch/$(ARCH)/src/exception.S \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/cuda.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/drivers/pic.c
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/debug/panic.s \
arch/$(KARCH)/src/fpu_context.S \
arch/$(KARCH)/src/boot/boot.S \
arch/$(KARCH)/src/ppc32.c \
arch/$(KARCH)/src/dummy.s \
arch/$(KARCH)/src/exception.S \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/drivers/pic.c
/branches/arm/kernel/arch/ppc32/_link.ld.in
1,11 → 1,11
/** PPC32 linker script
*
* umapped section:
* kernel text
* kernel data
* kernel text
* kernel data
* mapped section:
* kernel text
* kernel data
* kernel text
* kernel data
*
*/
 
27,7 → 27,7
unmapped_kdata_start = .;
}
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) {
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) {
ktext_start = .;
*(K_TEXT_START);
*(.text);
37,22 → 37,22
*(K_DATA_START);
*(.rodata);
*(.rodata.*);
*(.data); /* initialized data */
*(.data); /* initialized data */
*(.sdata);
*(.sdata2);
*(.sbss);
hardcoded_ktext_size = .;
LONG(ktext_end - ktext_start);
LONG(ktext_end - ktext_start);
hardcoded_kdata_size = .;
LONG(kdata_end - kdata_start);
hardcoded_load_address = .;
LONG(PA2KA(BOOT_OFFSET));
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
 
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
*(symtab.*); /* Symbol table, must be LAST symbol!*/
kdata_end = .;
}
}
/branches/arm/kernel/arch/arm32/include/machine.h
File deleted
/branches/arm/kernel/arch/arm32/include/console.h
File deleted
/branches/arm/kernel/arch/arm32/include/byteorder.h
File deleted
/branches/arm/kernel/arch/arm32/include/boot.h
File deleted
/branches/arm/kernel/arch/arm32/include/debug/print.h
File deleted
/branches/arm/kernel/arch/arm32/include/types.h
53,8 → 53,6
typedef unsigned long long uint64_t;
 
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
typedef uint32_t pfn_t;
64,10 → 62,11
typedef uint32_t unative_t;
typedef int32_t native_t;
 
typedef struct {
} fncptr_t;
 
#define PRIp "x" /**< Format for uintptr_t. */
#define PRIs "u" /**< Format for size_t. */
#define PRIc "u" /**< Format for count_t. */
#define PRIi "u" /**< Format for index_t. */
 
#define PRId8 "d" /**< Format for int8_t. */
#define PRId16 "d" /**< Format for int16_t. */
/branches/arm/kernel/arch/arm32/include/mm/page.h
94,21 → 94,21
 
/* Get PTE flags accessors for each level. */
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
get_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i))
get_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
get_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i))
get_pt_level1_flags((pte_level1_t *) (ptl3), (size_t) (i))
 
/* Set PTE flags accessors for each level. */
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
set_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i), (x))
set_pt_level0_flags((pte_level0_t *) (ptl0), (size_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
set_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i), (x))
set_pt_level1_flags((pte_level1_t *) (ptl3), (size_t) (i), (x))
 
/* Macros for querying the last-level PTE entries. */
#define PTE_VALID_ARCH(pte) \
193,9 → 193,8
static inline void set_ptl0_addr(pte_level0_t *pt)
{
asm volatile (
"mcr p15, 0, %0, c2, c0, 0 \n"
:
: "r"(pt)
"mcr p15, 0, %[pt], c2, c0, 0\n"
:: [pt] "r" (pt)
);
}
 
205,7 → 204,7
* @param pt Level 0 page table.
* @param i Index of the entry to return.
*/
static inline int get_pt_level0_flags(pte_level0_t *pt, index_t i)
static inline int get_pt_level0_flags(pte_level0_t *pt, size_t i)
{
pte_level0_t *p = &pt[i];
int np = (p->descriptor_type == PTE_DESCRIPTOR_NOT_PRESENT);
220,7 → 219,7
* @param pt Level 1 page table.
* @param i Index of the entry to return.
*/
static inline int get_pt_level1_flags(pte_level1_t *pt, index_t i)
static inline int get_pt_level1_flags(pte_level1_t *pt, size_t i)
{
pte_level1_t *p = &pt[i];
 
245,7 → 244,7
* @param i index of the entry to be changed
* @param flags new flags
*/
static inline void set_pt_level0_flags(pte_level0_t *pt, index_t i, int flags)
static inline void set_pt_level0_flags(pte_level0_t *pt, size_t i, int flags)
{
pte_level0_t *p = &pt[i];
 
273,7 → 272,7
* @param i Index of the entry to be changed.
* @param flags New flags.
*/
static inline void set_pt_level1_flags(pte_level1_t *pt, index_t i, int flags)
static inline void set_pt_level1_flags(pte_level1_t *pt, size_t i, int flags)
{
pte_level1_t *p = &pt[i];
/branches/arm/kernel/arch/arm32/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32mm
/** @addtogroup arm32mm
* @{
*/
/** @file
36,8 → 36,8
#ifndef KERN_arm32_FRAME_H_
#define KERN_arm32_FRAME_H_
 
#define FRAME_WIDTH 12 /* 4KB frames */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 12 /* 4KB frames */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
44,8 → 44,8
 
#include <arch/types.h>
 
#define BOOT_PAGE_TABLE_SIZE 0x4000
#define BOOT_PAGE_TABLE_ADDRESS 0x4000
#define BOOT_PAGE_TABLE_SIZE 0x4000
#define BOOT_PAGE_TABLE_ADDRESS 0x4000
 
#define BOOT_PAGE_TABLE_START_FRAME (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH)
#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH)
/branches/arm/kernel/arch/arm32/include/mm/tlb.h
36,9 → 36,6
#ifndef KERN_arm32_TLB_H_
#define KERN_arm32_TLB_H_
 
#define tlb_arch_init()
#define tlb_print()
 
#endif
 
/** @}
/branches/arm/kernel/arch/arm32/include/asm/boot.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/** @file
37,26 → 37,9
#define KERN_arm32_ASM_BOOT_H_
 
/** Size of a temporary stack used for initial kernel start. */
#define TEMP_STACK_SIZE 0x100
#define TEMP_STACK_SIZE 0x100
 
#ifndef __ASM__
 
/** Kernel entry point.
*
* Implemented in assembly. Copies boot_bootinfo (declared as bootinfo in
* boot/arch/arm32/loader/main.c) to #bootinfo struct. Then jumps to
* #arch_pre_main and #main_bsp.
*
* @param entry Entry point address (not used).
* @param boot_bootinfo Struct holding information about loaded tasks.
* @param bootinfo_size Size of the bootinfo structure.
*/
extern void kernel_image_start(void *entry, void *boot_bootinfo,
unsigned int bootinfo_size);
 
#endif
 
#endif
 
/** @}
*/
/branches/arm/kernel/arch/arm32/include/drivers/qemu.h
File deleted
/branches/arm/kernel/arch/arm32/include/drivers/pl050.h
File deleted
/branches/arm/kernel/arch/arm32/include/drivers/gxemul.h
38,43 → 38,33
#ifndef KERN_arm32_GXEMUL_H_
#define KERN_arm32_GXEMUL_H_
 
#include <console/chardev.h>
 
/** Last interrupt number (beginning from 0) whose status is probed
/** Last interrupt number (beginning from 0) whose status is probed
* from interrupt controller
*/
#define GXEMUL_IRQC_MAX_IRQ 8
#define GXEMUL_IRQC_MAX_IRQ 8
#define GXEMUL_KBD_IRQ 2
#define GXEMUL_TIMER_IRQ 4
 
/** Timer frequency */
#define GXEMUL_TIMER_FREQ 100
#define GXEMUL_TIMER_FREQ 100
 
/** Struct containing mappings of gxemul HW devices into kernel part
* of virtual address space.
*/
typedef struct {
uintptr_t videoram;
uintptr_t kbd;
uintptr_t rtc;
uintptr_t rtc_freq;
uintptr_t rtc_ack;
uintptr_t irqc;
uintptr_t irqc_mask;
uintptr_t irqc_unmask;
} gxemul_hw_map_t;
#define GXEMUL_KBD_ADDRESS 0x10000000
#define GXEMUL_MP_ADDRESS 0x11000000
#define GXEMUL_FB_ADDRESS 0x12000000
#define GXEMUL_RTC_ADDRESS 0x15000000
#define GXEMUL_IRQC_ADDRESS 0x16000000
 
extern void gxemul_hw_map_init(void);
extern void gxemul_console_init(devno_t devno);
extern void gxemul_release_console(void);
extern void gxemul_grab_console(void);
extern void gxemul_timer_irq_start(void);
extern void gxemul_debug_putc(char ch);
extern void gxemul_cpu_halt(void);
extern void gxemul_irq_exception(int exc_no, istate_t *istate);
extern size_t gxemul_get_memory_size(void);
extern uintptr_t gxemul_get_fb_address(void);
extern void gxemul_fb_init(void);
extern void gxemul_frame_init(void);
extern void *gxemul_kbd;
extern void *gxemul_rtc;
extern void *gxemul_irqc;
 
#define GXEMUL_HALT_OFFSET 0x010
#define GXEMUL_RTC_FREQ_OFFSET 0x100
#define GXEMUL_MP_MEMSIZE_OFFSET 0x090
#define GXEMUL_RTC_ACK_OFFSET 0x110
 
extern void gxemul_init(void);
 
#endif
 
/** @}
/branches/arm/kernel/arch/arm32/include/arch.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/** @file
36,6 → 36,26
#ifndef KERN_arm32_ARCH_H_
#define KERN_arm32_ARCH_H_
 
#define TASKMAP_MAX_RECORDS 32
#define CPUMAP_MAX_RECORDS 32
 
#define BOOTINFO_TASK_NAME_BUFLEN 32
 
#include <typedefs.h>
 
typedef struct {
uintptr_t addr;
uint32_t size;
char name[BOOTINFO_TASK_NAME_BUFLEN];
} utask_t;
 
typedef struct {
uint32_t cnt;
utask_t tasks[TASKMAP_MAX_RECORDS];
} bootinfo_t;
 
extern void arch_pre_main(void *entry, bootinfo_t *bootinfo);
 
#endif
 
/** @}
/branches/arm/kernel/arch/arm32/include/asm.h
26,10 → 26,10
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/** @file
/** @file
* @brief Declarations of functions implemented in assembly.
*/
 
36,6 → 36,7
#ifndef KERN_arm32_ASM_H_
#define KERN_arm32_ASM_H_
 
#include <typedefs.h>
#include <arch/types.h>
#include <arch/stack.h>
#include <config.h>
46,19 → 47,50
{
}
 
static inline void pio_write_8(ioport8_t *port, uint8_t v)
{
*port = v;
}
 
static inline void pio_write_16(ioport16_t *port, uint16_t v)
{
*port = v;
}
 
static inline void pio_write_32(ioport32_t *port, uint32_t v)
{
*port = v;
}
 
static inline uint8_t pio_read_8(ioport8_t *port)
{
return *port;
}
 
static inline uint16_t pio_read_16(ioport16_t *port)
{
return *port;
}
 
static inline uint32_t pio_read_32(ioport32_t *port)
{
return *port;
}
 
/** Return base address of current stack.
*
*
* Return the base address of the current stack.
* The stack is assumed to be STACK_SIZE bytes long.
* The stack must start on page boundary.
*
*/
static inline uintptr_t get_stack_base(void)
{
uintptr_t v;
asm volatile (
"and %0, sp, %1\n"
: "=r" (v)
: "r" (~(STACK_SIZE - 1))
"and %[v], sp, %[size]\n"
: [v] "=r" (v)
: [size] "r" (~(STACK_SIZE - 1))
);
return v;
}
/branches/arm/kernel/arch/arm32/include/regutils.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/**
57,7 → 57,10
static inline uint32_t nm## _status_reg_read(void) \
{ \
uint32_t retval; \
asm volatile("mrs %0, " #reg : "=r" (retval)); \
asm volatile( \
"mrs %[retval], " #reg \
: [retval] "=r" (retval) \
); \
return retval; \
}
 
64,7 → 67,10
#define GEN_STATUS_WRITE(nm,reg,fieldname, field) \
static inline void nm## _status_reg_ ##fieldname## _write(uint32_t value) \
{ \
asm volatile("msr " #reg "_" #field ", %0" : : "r" (value)); \
asm volatile( \
"msr " #reg "_" #field ", %[value]" \
:: [value] "r" (value) \
); \
}
 
 
/branches/arm/kernel/arch/arm32/include/atomic.h
26,10 → 26,10
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/** @file
/** @file
* @brief Atomic operations.
*/
 
42,26 → 42,26
* @param i Value to be added.
*
* @return Value after addition.
*
*/
static inline long atomic_add(atomic_t *val, int i)
{
int ret;
volatile long *mem = &(val->count);
 
asm volatile (
"1:\n"
"ldr r2, [%1] \n"
"add r3, r2, %2 \n"
"str r3, %0 \n"
"swp r3, r3, [%1] \n"
"cmp r3, r2 \n"
"bne 1b \n"
 
: "=m" (ret)
: "r" (mem), "r" (i)
"1:\n"
"ldr r2, [%[mem]]\n"
"add r3, r2, %[i]\n"
"str r3, %[ret]\n"
"swp r3, r3, [%[mem]]\n"
"cmp r3, r2\n"
"bne 1b\n"
: [ret] "=m" (ret)
: [mem] "r" (mem), [i] "r" (i)
: "r3", "r2"
);
 
return ret;
}
 
/branches/arm/kernel/arch/arm32/include/barrier.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/** @file
39,12 → 39,12
/*
* TODO: implement true ARM memory barriers for macros below.
*/
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory")
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory")
 
#define memory_barrier() asm volatile ("" ::: "memory")
#define read_barrier() asm volatile ("" ::: "memory")
#define write_barrier() asm volatile ("" ::: "memory")
#define memory_barrier() asm volatile ("" ::: "memory")
#define read_barrier() asm volatile ("" ::: "memory")
#define write_barrier() asm volatile ("" ::: "memory")
 
#define smc_coherence(a)
#define smc_coherence_block(a, l)
/branches/arm/kernel/arch/arm32/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf32-littlearm
BFD_ARCH = arm
BFD = binary
39,68 → 35,28
TARGET = arm-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm
 
KERNEL_LOAD_ADDRESS = 0x80200000
 
ifeq ($(MACHINE), gxemul_testarm)
DMACHINE = MACHINE_GXEMUL_TESTARM
else ifeq ($(MACHINE), qemu_icp)
DMACHINE = MACHINE_QEMU_ICP
endif
 
ATSIGN = %
 
GCC_CFLAGS += -fno-zero-initialized-in-bss
 
DEFS += -D__32_BITS__ -DKERNEL_LOAD_ADDRESS=$(KERNEL_LOAD_ADDRESS) -D$(DMACHINE)
BITS = 32
ENDIANESS = LE
 
# Compile with framebuffer support
 
ifeq ($(CONFIG_FB), y)
DEFS += -DCONFIG_FB -DFB_INVERT_ENDIAN
endif
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with support for address space identifiers.
#
# no HW support for ASIDs
#CONFIG_ASID = y
#CONFIG_ASID_FIFO = y
CONFIG_PL050 = y
 
## Compile with support with software division and multiplication.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/start.S \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/arm32.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/dummy.S \
arch/$(ARCH)/src/panic.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/debug/print.c \
arch/$(ARCH)/src/console.c \
arch/$(ARCH)/src/exception.c \
arch/$(ARCH)/src/userspace.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/mm/page_fault.c
 
ifeq ($(MACHINE), gxemul_testarm)
ARCH_SOURCES += arch/$(ARCH)/src/drivers/gxemul.c
else ifeq ($(MACHINE), qemu_icp)
ARCH_SOURCES += arch/$(ARCH)/src/drivers/qemu.c \
arch/$(ARCH)/src/drivers/pl050.c
endif
 
arch/$(KARCH)/src/start.S \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/arm32.c \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/dummy.S \
arch/$(KARCH)/src/panic.S \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/exception.c \
arch/$(KARCH)/src/userspace.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/mm/page_fault.c \
arch/$(KARCH)/src/drivers/gxemul.c
/branches/arm/kernel/arch/arm32/src/debug/print.c
File deleted
/branches/arm/kernel/arch/arm32/src/console.c
File deleted
/branches/arm/kernel/arch/arm32/src/mm/tlb.c
48,7 → 48,7
asm volatile (
"eor r1, r1\n"
"mcr p15, 0, r1, c8, c7, 0\n"
: : : "r1"
::: "r1"
);
}
 
68,9 → 68,8
static inline void invalidate_page(uintptr_t page)
{
asm volatile (
"mcr p15, 0, %0, c8, c7, 1"
:
: "r" (page)
"mcr p15, 0, %[page], c8, c7, 1\n"
:: [page] "r" (page)
);
}
 
81,7 → 80,7
* @param page Address of the first page whose entry is to be invalidated.
* @param cnt Number of entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, size_t cnt)
{
unsigned int i;
 
89,5 → 88,13
invalidate_page(page + i * PAGE_SIZE);
}
 
void tlb_arch_init(void)
{
}
 
void tlb_print(void)
{
}
 
/** @}
*/
/branches/arm/kernel/arch/arm32/src/mm/page_fault.c
34,7 → 34,6
*/
#include <panic.h>
#include <arch/exception.h>
#include <arch/debug/print.h>
#include <arch/mm/page_fault.h>
#include <mm/as.h>
#include <genarch/mm/page_pt.h>
49,12 → 48,13
static inline fault_status_t read_fault_status_register(void)
{
fault_status_union_t fsu;
 
/* fault status is stored in CP15 register 5 */
asm volatile (
"mrc p15, 0, %0, c5, c0, 0"
: "=r"(fsu.dummy)
"mrc p15, 0, %[dummy], c5, c0, 0"
: [dummy] "=r" (fsu.dummy)
);
return fsu.fs;
}
 
61,17 → 61,18
/** Returns FAR (fault address register) content.
*
* @return FAR (fault address register) content (address that caused a page
* fault)
* fault)
*/
static inline uintptr_t read_fault_address_register(void)
{
uintptr_t ret;
 
/* fault adress is stored in CP15 register 6 */
asm volatile (
"mrc p15, 0, %0, c6, c0, 0"
: "=r"(ret)
"mrc p15, 0, %[ret], c6, c0, 0"
: [ret] "=r" (ret)
);
return ret;
}
 
80,29 → 81,26
* @param instr Instruction
*
* @return true when instruction is load/store, false otherwise
*
*/
static inline bool is_load_store_instruction(instruction_t instr)
{
/* load store immediate offset */
if (instr.type == 0x2) {
if (instr.type == 0x2)
return true;
}
 
/* load store register offset */
if (instr.type == 0x3 && instr.bit4 == 0) {
if ((instr.type == 0x3) && (instr.bit4 == 0))
return true;
}
 
/* load store multiple */
if (instr.type == 0x4) {
if (instr.type == 0x4)
return true;
}
 
/* oprocessor load/store */
if (instr.type == 0x6) {
if (instr.type == 0x6)
return true;
}
 
return false;
}
 
115,12 → 113,11
static inline bool is_swap_instruction(instruction_t instr)
{
/* swap, swapb instruction */
if (instr.type == 0x0 &&
(instr.opcode == 0x8 || instr.opcode == 0xa) &&
instr.access == 0x0 && instr.bits567 == 0x4 && instr.bit4 == 1) {
if ((instr.type == 0x0) &&
((instr.opcode == 0x8) || (instr.opcode == 0xa)) &&
(instr.access == 0x0) && (instr.bits567 == 0x4) && (instr.bit4 == 1))
return true;
}
 
return false;
}
 
142,8 → 139,8
 
/* undefined instructions */
if (instr.condition == 0xf) {
panic("page_fault - instruction doesn't access memory "
"(instr_code: %x, badvaddr:%x)", instr, badvaddr);
panic("page_fault - instruction does not access memory "
"(instr_code: %x, badvaddr:%x).", instr, badvaddr);
return PF_ACCESS_EXEC;
}
 
162,7 → 159,7
}
 
panic("page_fault - instruction doesn't access memory "
"(instr_code: %x, badvaddr:%x)", instr, badvaddr);
"(instr_code: %x, badvaddr:%x).", instr, badvaddr);
 
return PF_ACCESS_EXEC;
}
184,12 → 181,12
 
if (ret == AS_PF_FAULT) {
print_istate(istate);
dprintf("page fault - pc: %x, va: %x, status: %x(%x), "
printf("page fault - pc: %x, va: %x, status: %x(%x), "
"access:%d\n", istate->pc, badvaddr, fsr.status, fsr,
access);
 
fault_if_from_uspace(istate, "Page fault: %#x", badvaddr);
panic("page fault\n");
fault_if_from_uspace(istate, "Page fault: %#x.", badvaddr);
panic("Page fault.");
}
}
 
203,9 → 200,9
int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate);
 
if (ret == AS_PF_FAULT) {
dprintf("prefetch_abort\n");
printf("prefetch_abort\n");
print_istate(istate);
panic("page fault - prefetch_abort at address: %x\n",
panic("page fault - prefetch_abort at address: %x.",
istate->pc);
}
}
/branches/arm/kernel/arch/arm32/src/mm/frame.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32mm
/** @addtogroup arm32mm
* @{
*/
/** @file
35,9 → 35,8
 
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <arch/machine.h>
#include <arch/drivers/gxemul.h>
#include <config.h>
#include <arch/debug/print.h>
 
/** Address of the last frame in the memory. */
uintptr_t last_frame = 0;
45,26 → 44,23
/** Creates memory zones. */
void frame_arch_init(void)
{
/* all memory as one zone */
zone_create(0, ADDR2PFN(machine_get_memory_size()),
last_frame = *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
/* All memory as one zone */
zone_create(0, ADDR2PFN(last_frame),
BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0);
last_frame = machine_get_memory_size();
 
/* blacklist boot page table */
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME,
BOOT_PAGE_TABLE_SIZE_IN_FRAMES);
 
/* Machine specific frame initialization */
machine_frame_init();
}
 
/** Frees the boot page table. */
void boot_page_table_free(void)
{
int i;
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++) {
unsigned int i;
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++)
frame_free(i * FRAME_SIZE + BOOT_PAGE_TABLE_ADDRESS);
}
}
 
/** @}
/branches/arm/kernel/arch/arm32/src/mm/page.c
51,19 → 51,15
*/
void page_arch_init(void)
{
int flags = PAGE_CACHEABLE;
page_mapping_operations = &pt_mapping_operations;
uintptr_t cur;
int flags;
 
page_mapping_operations = &pt_mapping_operations;
 
flags = PAGE_CACHEABLE;
 
/* PA2KA(identity) mapping for all frames until last_frame */
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
/* Kernel identity mapping */
for (cur = 0; cur < last_frame; cur += FRAME_SIZE)
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
}
/* create mapping for exception table at high offset */
/* Create mapping for exception table at high offset */
#ifdef HIGH_EXCEPTION_VECTORS
void *virtaddr = frame_alloc(ONE_FRAME, FRAME_KA);
page_mapping_insert(AS_KERNEL, EXC_BASE_ADDRESS, KA2PA(virtaddr), flags);
70,9 → 66,9
#else
#error "Only high exception vector supported now"
#endif
 
as_switch(NULL, AS_KERNEL);
 
boot_page_table_free();
}
 
90,10 → 86,10
{
if (last_frame + ALIGN_UP(size, PAGE_SIZE) >
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) {
panic("Unable to map physical memory %p (%d bytes)",
panic("Unable to map physical memory %p (%d bytes).",
physaddr, size)
}
 
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) {
101,7 → 97,7
physaddr + PFN2ADDR(i),
PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
}
 
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
return virtaddr;
}
/branches/arm/kernel/arch/arm32/src/arm32.c
34,36 → 34,37
*/
 
#include <arch.h>
#include <arch/boot.h>
#include <config.h>
#include <arch/console.h>
#include <ddi/device.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <genarch/drivers/dsrln/dsrlnin.h>
#include <genarch/drivers/dsrln/dsrlnout.h>
#include <genarch/srln/srln.h>
#include <sysinfo/sysinfo.h>
#include <console/console.h>
#include <ddi/irq.h>
#include <arch/debug/print.h>
#include <arch/drivers/gxemul.h>
#include <print.h>
#include <config.h>
#include <interrupt.h>
#include <arch/regutils.h>
#include <arch/machine.h>
#include <userspace.h>
#include <macros.h>
#include <string.h>
 
/** Information about loaded tasks. */
bootinfo_t bootinfo;
 
/** Performs arm32 specific initialization before main_bsp() is called. */
void arch_pre_main(void)
/** Performs arm32-specific initialization before main_bsp() is called. */
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo)
{
unsigned int i;
 
init.cnt = bootinfo.cnt;
 
for (i = 0; i < bootinfo.cnt; ++i) {
init.tasks[i].addr = bootinfo.tasks[i].addr;
init.tasks[i].size = bootinfo.tasks[i].size;
init.cnt = bootinfo->cnt;
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); ++i) {
init.tasks[i].addr = bootinfo->tasks[i].addr;
init.tasks[i].size = bootinfo->tasks[i].size;
str_cpy(init.tasks[i].name, CONFIG_TASK_NAME_BUFLEN,
bootinfo->tasks[i].name);
}
}
 
/** Performs arm32 specific initialization before mm is initialized. */
76,18 → 77,27
/** Performs arm32 specific initialization afterr mm is initialized. */
void arch_post_mm_init(void)
{
machine_hw_map_init();
 
gxemul_init();
/* Initialize exception dispatch table */
exception_init();
 
interrupt_init();
console_init(device_assign_devno());
 
#ifdef CONFIG_FB
machine_fb_init();
#endif
fb_properties_t prop = {
.addr = GXEMUL_FB_ADDRESS,
.offset = 0,
.x = 640,
.y = 480,
.scan = 1920,
.visual = VISUAL_BGR_8_8_8,
};
fb_init(&prop);
#else
#ifdef CONFIG_ARM_PRN
dsrlnout_init((ioport8_t *) gxemul_kbd);
#endif /* CONFIG_ARM_PRN */
#endif /* CONFIG_FB */
}
 
/** Performs arm32 specific tasks needed after cpu is initialized.
116,6 → 126,30
*/
void arch_post_smp_init(void)
{
#ifdef CONFIG_ARM_KBD
/*
* Initialize the GXemul keyboard port. Then initialize the serial line
* module and connect it to the GXemul keyboard.
*/
dsrlnin_instance_t *dsrlnin_instance
= dsrlnin_init((dsrlnin_t *) gxemul_kbd, GXEMUL_KBD_IRQ);
if (dsrlnin_instance) {
srln_instance_t *srln_instance = srln_init();
if (srln_instance) {
indev_t *sink = stdin_wire();
indev_t *srln = srln_wire(srln_instance, sink);
dsrlnin_wire(dsrlnin_instance, srln);
}
}
/*
* 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, GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, (unative_t) gxemul_kbd);
#endif
}
 
 
149,7 → 183,8
/** Halts CPU. */
void cpu_halt(void)
{
machine_cpu_halt();
*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET))
= 0;
}
 
/** Reboot. */
156,9 → 191,35
void arch_reboot()
{
/* not implemented */
for (;;)
;
while (1);
}
 
/** 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;
}
 
/** Acquire console back for kernel. */
void arch_grab_console(void)
{
#ifdef CONFIG_FB
fb_redraw();
#endif
}
 
/** Return console to userspace. */
void arch_release_console(void)
{
}
 
/** @}
*/
/branches/arm/kernel/arch/arm32/src/asm.S
30,6 → 30,7
.text
 
.global memsetb
.global memsetw
.global memcpy
.global memcpy_from_uspace
.global memcpy_to_uspace
39,6 → 40,9
memsetb:
b _memsetb
 
memsetw:
b _memsetw
 
memcpy:
memcpy_from_uspace:
memcpy_to_uspace:
/branches/arm/kernel/arch/arm32/src/exception.c
34,13 → 34,12
*/
 
#include <arch/exception.h>
#include <arch/debug/print.h>
#include <arch/memstr.h>
#include <arch/regutils.h>
#include <interrupt.h>
#include <arch/machine.h>
#include <arch/mm/page_fault.h>
#include <arch/barrier.h>
#include <arch/drivers/gxemul.h>
#include <print.h>
#include <syscall/syscall.h>
 
63,57 → 62,60
*
* Temporary exception stack is used to save a few registers
* before stack switch takes place.
*
*/
inline static void setup_stack_and_save_regs()
{
asm volatile(
"ldr r13, =exc_stack \n"
"stmfd r13!, {r0} \n"
"mrs r0, spsr \n"
"and r0, r0, #0x1f \n"
"cmp r0, #0x10 \n"
"bne 1f \n"
 
asm volatile (
"ldr r13, =exc_stack\n"
"stmfd r13!, {r0}\n"
"mrs r0, spsr\n"
"and r0, r0, #0x1f\n"
"cmp r0, #0x10\n"
"bne 1f\n"
/* prev mode was usermode */
"ldmfd r13!, {r0} \n"
"ldr r13, =supervisor_sp \n"
"ldr r13, [r13] \n"
"stmfd r13!, {lr} \n"
"stmfd r13!, {r0-r12} \n"
"stmfd r13!, {r13, lr}^ \n"
"mrs r0, spsr \n"
"stmfd r13!, {r0} \n"
"b 2f \n"
 
"ldmfd r13!, {r0}\n"
"ldr r13, =supervisor_sp\n"
"ldr r13, [r13]\n"
"stmfd r13!, {lr}\n"
"stmfd r13!, {r0-r12}\n"
"stmfd r13!, {r13, lr}^\n"
"mrs r0, spsr\n"
"stmfd r13!, {r0}\n"
"b 2f\n"
/* mode was not usermode */
"1:\n"
"stmfd r13!, {r1, r2, r3} \n"
"mrs r1, cpsr \n"
"mov r2, lr \n"
"bic r1, r1, #0x1f \n"
"orr r1, r1, r0 \n"
"mrs r0, cpsr \n"
"msr cpsr_c, r1 \n"
 
"mov r3, r13 \n"
"stmfd r13!, {r2} \n"
"mov r2, lr \n"
"stmfd r13!, {r4-r12} \n"
"mov r1, r13 \n"
/* the following two lines are for debugging */
"mov sp, #0 \n"
"mov lr, #0 \n"
"msr cpsr_c, r0 \n"
 
"ldmfd r13!, {r4, r5, r6, r7} \n"
"stmfd r1!, {r4, r5, r6} \n"
"stmfd r1!, {r7} \n"
"stmfd r1!, {r2} \n"
"stmfd r1!, {r3} \n"
"mrs r0, spsr \n"
"stmfd r1!, {r0} \n"
"mov r13, r1 \n"
"2:\n"
"1:\n"
"stmfd r13!, {r1, r2, r3}\n"
"mrs r1, cpsr\n"
"mov r2, lr\n"
"bic r1, r1, #0x1f\n"
"orr r1, r1, r0\n"
"mrs r0, cpsr\n"
"msr cpsr_c, r1\n"
"mov r3, r13\n"
"stmfd r13!, {r2}\n"
"mov r2, lr\n"
"stmfd r13!, {r4-r12}\n"
"mov r1, r13\n"
/* the following two lines are for debugging */
"mov sp, #0\n"
"mov lr, #0\n"
"msr cpsr_c, r0\n"
"ldmfd r13!, {r4, r5, r6, r7}\n"
"stmfd r1!, {r4, r5, r6}\n"
"stmfd r1!, {r7}\n"
"stmfd r1!, {r2}\n"
"stmfd r1!, {r3}\n"
"mrs r0, spsr\n"
"stmfd r1!, {r0}\n"
"mov r13, r1\n"
"2:\n"
);
}
 
189,10 → 191,13
}
 
/** Calls exception dispatch routine. */
#define CALL_EXC_DISPATCH(exception) \
asm("mov r0, %0" : : "i" (exception)); \
asm("mov r1, r13"); \
asm("bl exc_dispatch");
#define CALL_EXC_DISPATCH(exception) \
asm volatile ( \
"mov r0, %[exc]\n" \
"mov r1, r13\n" \
"bl exc_dispatch\n" \
:: [exc] "i" (exception) \
);\
 
/** General exception handler.
*
201,9 → 206,9
*
* @param exception Exception number.
*/
#define PROCESS_EXCEPTION(exception) \
setup_stack_and_save_regs(); \
CALL_EXC_DISPATCH(exception) \
#define PROCESS_EXCEPTION(exception) \
setup_stack_and_save_regs(); \
CALL_EXC_DISPATCH(exception) \
load_regs();
 
/** Updates specified exception vector to jump to given handler.
254,7 → 259,10
/** Low-level Prefetch Abort Exception handler. */
static void prefetch_abort_exception_entry(void)
{
asm("sub lr, lr, #4");
asm volatile (
"sub lr, lr, #4"
);
PROCESS_EXCEPTION(EXC_PREFETCH_ABORT);
}
 
261,7 → 269,10
/** Low-level Data Abort Exception handler. */
static void data_abort_exception_entry(void)
{
asm("sub lr, lr, #8");
asm volatile (
"sub lr, lr, #8"
);
PROCESS_EXCEPTION(EXC_DATA_ABORT);
}
 
273,7 → 284,10
*/
static void irq_exception_entry(void)
{
asm("sub lr, lr, #4");
asm volatile (
"sub lr, lr, #4"
);
setup_stack_and_save_regs();
switch_to_irq_servicing_mode();
293,6 → 307,12
istate->r3, istate->r4, istate->r5, istate->r6);
}
 
/** Returns the mask of active interrupts. */
static inline uint32_t gxemul_irqc_get_sources(void)
{
return *((uint32_t *) gxemul_irqc);
}
 
/** Interrupt Exception handler.
*
* Determines the sources of interrupt and calls their handlers.
299,7 → 319,23
*/
static void irq_exception(int exc_no, istate_t *istate)
{
machine_irq_exception(exc_no, istate);
uint32_t sources = gxemul_irqc_get_sources();
unsigned int i;
for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
printf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
/** Fills exception vectors with appropriate exception handlers. */
323,7 → 359,7
install_handler((unsigned) irq_exception_entry,
(unsigned *) EXC_IRQ_VEC);
install_handler((unsigned)fiq_exception_entry,
install_handler((unsigned) fiq_exception_entry,
(unsigned *) EXC_FIQ_VEC);
}
 
333,17 → 369,23
{
uint32_t control_reg;
asm volatile("mrc p15, 0, %0, c1, c1" : "=r" (control_reg));
asm volatile (
"mrc p15, 0, %[control_reg], c1, c1"
: [control_reg] "=r" (control_reg)
);
/* switch on the high vectors bit */
control_reg |= CP15_R1_HIGH_VECTORS_BIT;
asm volatile("mcr p15, 0, %0, c1, c1" : : "r" (control_reg));
asm volatile (
"mcr p15, 0, %[control_reg], c1, c1"
:: [control_reg] "r" (control_reg)
);
}
#endif
 
/** Initializes exception handling.
*
*
* Installs low-level exception handlers and then registers
* exceptions and their handlers to kernel exception dispatcher.
*/
367,18 → 409,18
*/
void print_istate(istate_t *istate)
{
dprintf("istate dump:\n");
 
dprintf(" r0: %x r1: %x r2: %x r3: %x\n",
printf("istate dump:\n");
printf(" r0: %x r1: %x r2: %x r3: %x\n",
istate->r0, istate->r1, istate->r2, istate->r3);
dprintf(" r4: %x r5: %x r6: %x r7: %x\n",
printf(" r4: %x r5: %x r6: %x r7: %x\n",
istate->r4, istate->r5, istate->r6, istate->r7);
dprintf(" r8: %x r8: %x r10: %x r11: %x\n",
printf(" r8: %x r8: %x r10: %x r11: %x\n",
istate->r8, istate->r9, istate->r10, istate->r11);
dprintf(" r12: %x sp: %x lr: %x spsr: %x\n",
printf(" r12: %x sp: %x lr: %x spsr: %x\n",
istate->r12, istate->sp, istate->lr, istate->spsr);
 
dprintf(" pc: %x\n", istate->pc);
printf(" pc: %x\n", istate->pc);
}
 
/** @}
/branches/arm/kernel/arch/arm32/src/panic.S
31,5 → 31,5
.global panic_printf
 
panic_printf:
bl debug_printf
bl printf
bl cpu_halt
/branches/arm/kernel/arch/arm32/src/interrupt.c
35,13 → 35,16
 
#include <arch/asm.h>
#include <arch/regutils.h>
#include <arch/drivers/gxemul.h>
#include <ddi/irq.h>
#include <arch/machine.h>
#include <ddi/device.h>
#include <interrupt.h>
 
/** Initial size of a table holding interrupt handlers. */
#define IRQ_COUNT 8
 
static irq_t gxemul_timer_irq;
 
/** Disable interrupts.
*
* @return Old interrupt priority level.
49,7 → 52,7
ipl_t interrupts_disable(void)
{
ipl_t ipl = current_status_reg_read();
 
current_status_reg_control_write(STATUS_REG_IRQ_DISABLED_BIT | ipl);
return ipl;
62,9 → 65,9
ipl_t interrupts_enable(void)
{
ipl_t ipl = current_status_reg_read();
 
current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT);
 
return ipl;
}
 
88,6 → 91,41
return current_status_reg_read();
}
 
/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void gxemul_timer_start(uint32_t frequency)
{
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET))
= frequency;
}
 
static irq_ownership_t gxemul_timer_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void gxemul_timer_irq_handler(irq_t *irq)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
/* acknowledge tick */
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET))
= 0;
}
 
/** Initialize basic tables for exception dispatching
* and starts the timer.
*/
94,7 → 132,16
void interrupt_init(void)
{
irq_init(IRQ_COUNT, IRQ_COUNT);
machine_timer_irq_start();
irq_initialize(&gxemul_timer_irq);
gxemul_timer_irq.devno = device_assign_devno();
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
gxemul_timer_irq.claim = gxemul_timer_claim;
gxemul_timer_irq.handler = gxemul_timer_irq_handler;
irq_register(&gxemul_timer_irq);
gxemul_timer_start(GXEMUL_TIMER_FREQ);
}
 
/** @}
/branches/arm/kernel/arch/arm32/src/drivers/qemu.c
File deleted
/branches/arm/kernel/arch/arm32/src/drivers/pl050.c
File deleted
/branches/arm/kernel/arch/arm32/src/drivers/gxemul.c
33,374 → 33,19
* @brief GXemul drivers.
*/
 
#include <interrupt.h>
#include <ipc/irq.h>
#include <console/chardev.h>
#include <arch/drivers/gxemul.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <print.h>
#include <ddi/device.h>
#include <mm/page.h>
#include <arch/machine.h>
#include <arch/debug/print.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
 
/* Addresses of devices. */
#define GXEMUL_VIDEORAM 0x10000000
#define GXEMUL_KBD 0x10000000
#define GXEMUL_HALT_OFFSET 0x10
#define GXEMUL_RTC 0x15000000
#define GXEMUL_RTC_FREQ_OFFSET 0x100
#define GXEMUL_RTC_ACK_OFFSET 0x110
#define GXEMUL_IRQC 0x16000000
#define GXEMUL_IRQC_MASK_OFFSET 0x4
#define GXEMUL_IRQC_UNMASK_OFFSET 0x8
#define GXEMUL_MP 0x11000000
#define GXEMUL_MP_MEMSIZE_OFFSET 0x0090
#define GXEMUL_FB 0x12000000
void *gxemul_kbd;
void *gxemul_rtc;
void *gxemul_irqc;
 
/* IRQs */
#define GXEMUL_KBD_IRQ 2
#define GXEMUL_TIMER_IRQ 4
 
static gxemul_hw_map_t gxemul_hw_map;
static chardev_t console;
static irq_t gxemul_console_irq;
static irq_t gxemul_timer_irq;
 
static bool hw_map_init_called = false;
 
static void gxemul_kbd_enable(chardev_t *dev);
static void gxemul_kbd_disable(chardev_t *dev);
static void gxemul_write(chardev_t *dev, const char ch);
static char gxemul_do_read(chardev_t *dev);
 
static chardev_operations_t gxemul_ops = {
.resume = gxemul_kbd_enable,
.suspend = gxemul_kbd_disable,
.write = gxemul_write,
.read = gxemul_do_read,
};
 
 
/** Returns the mask of active interrupts. */
static inline uint32_t gxemul_irqc_get_sources(void)
void gxemul_init(void)
{
return *((uint32_t *) gxemul_hw_map.irqc);
gxemul_kbd = (void *) hw_map(GXEMUL_KBD_ADDRESS, PAGE_SIZE);
gxemul_rtc = (void *) hw_map(GXEMUL_RTC_ADDRESS, PAGE_SIZE);
gxemul_irqc = (void *) hw_map(GXEMUL_IRQC_ADDRESS, PAGE_SIZE);
}
 
 
/** Masks interrupt.
*
* @param irq interrupt number
*/
static inline void gxemul_irqc_mask(uint32_t irq)
{
*((uint32_t *) gxemul_hw_map.irqc_mask) = irq;
}
 
 
/** Unmasks interrupt.
*
* @param irq interrupt number
*/
static inline void gxemul_irqc_unmask(uint32_t irq)
{
*((uint32_t *) gxemul_hw_map.irqc_unmask) = irq;
}
 
/** Initializes the gxemul testarm frame buffer */
void gxemul_fb_init(void)
{
fb_init(gxemul_get_fb_address(), 640, 480, 1920, VISUAL_RGB_8_8_8);
}
 
/** Initializes #gxemul_hw_map. */
void gxemul_hw_map_init(void)
{
gxemul_hw_map.videoram = hw_map(GXEMUL_VIDEORAM, PAGE_SIZE);
gxemul_hw_map.kbd = hw_map(GXEMUL_KBD, PAGE_SIZE);
gxemul_hw_map.rtc = hw_map(GXEMUL_RTC, PAGE_SIZE);
gxemul_hw_map.irqc = hw_map(GXEMUL_IRQC, PAGE_SIZE);
 
gxemul_hw_map.rtc_freq = gxemul_hw_map.rtc + GXEMUL_RTC_FREQ_OFFSET;
gxemul_hw_map.rtc_ack = gxemul_hw_map.rtc + GXEMUL_RTC_ACK_OFFSET;
gxemul_hw_map.irqc_mask = gxemul_hw_map.irqc + GXEMUL_IRQC_MASK_OFFSET;
gxemul_hw_map.irqc_unmask = gxemul_hw_map.irqc +
GXEMUL_IRQC_UNMASK_OFFSET;
 
hw_map_init_called = true;
}
 
 
/** Putchar that works with gxemul.
*
* @param dev Not used.
* @param ch Characted to be printed.
*/
static void gxemul_write(chardev_t *dev, const char ch)
{
*((char *) gxemul_hw_map.videoram) = ch;
}
 
/** Enables gxemul keyboard (interrupt unmasked).
*
* @param dev Not used.
*
* Called from getc().
*/
static void gxemul_kbd_enable(chardev_t *dev)
{
gxemul_irqc_unmask(GXEMUL_KBD_IRQ);
}
 
/** Disables gxemul keyboard (interrupt masked).
*
* @param dev not used
*
* Called from getc().
*/
static void gxemul_kbd_disable(chardev_t *dev)
{
gxemul_irqc_mask(GXEMUL_KBD_IRQ);
}
 
/** Read character using polling, assume interrupts disabled.
*
* @param dev Not used.
*/
static char gxemul_do_read(chardev_t *dev)
{
char ch;
 
while (1) {
ch = *((volatile char *) gxemul_hw_map.kbd);
if (ch) {
if (ch == '\r')
return '\n';
if (ch == 0x7f)
return '\b';
return ch;
}
}
}
 
/** Process keyboard interrupt.
*
* @param irq IRQ information.
* @param arg Not used.
*/
static void gxemul_irq_handler(irq_t *irq, void *arg, ...)
{
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) {
ipc_irq_send_notif(irq);
} else {
char ch = 0;
ch = *((char *) gxemul_hw_map.kbd);
if (ch == '\r') {
ch = '\n';
}
if (ch == 0x7f) {
ch = '\b';
}
chardev_push_character(&console, ch);
}
}
 
static irq_ownership_t gxemul_claim(void)
{
return IRQ_ACCEPT;
}
 
 
/** Acquire console back for kernel. */
void gxemul_grab_console(void)
{
ipl_t ipl = interrupts_disable();
spinlock_lock(&gxemul_console_irq.lock);
gxemul_console_irq.notif_cfg.notify = false;
spinlock_unlock(&gxemul_console_irq.lock);
interrupts_restore(ipl);
}
 
/** Return console to userspace. */
void gxemul_release_console(void)
{
ipl_t ipl = interrupts_disable();
spinlock_lock(&gxemul_console_irq.lock);
if (gxemul_console_irq.notif_cfg.answerbox) {
gxemul_console_irq.notif_cfg.notify = true;
}
spinlock_unlock(&gxemul_console_irq.lock);
interrupts_restore(ipl);
}
 
/** Initializes console object representing gxemul console.
*
* @param devno device number.
*/
void gxemul_console_init(devno_t devno)
{
chardev_initialize("gxemul_console", &console, &gxemul_ops);
stdin = &console;
stdout = &console;
irq_initialize(&gxemul_console_irq);
gxemul_console_irq.devno = devno;
gxemul_console_irq.inr = GXEMUL_KBD_IRQ;
gxemul_console_irq.claim = gxemul_claim;
gxemul_console_irq.handler = gxemul_irq_handler;
irq_register(&gxemul_console_irq);
gxemul_irqc_unmask(GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, gxemul_hw_map.kbd);
}
 
/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void gxemul_timer_start(uint32_t frequency)
{
*((uint32_t*) gxemul_hw_map.rtc_freq) = frequency;
}
 
static irq_ownership_t gxemul_timer_claim(void)
{
return IRQ_ACCEPT;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
 
/* acknowledge tick */
*((uint32_t*) gxemul_hw_map.rtc_ack) = 0;
}
 
/** Initializes and registers timer interrupt handler. */
static void gxemul_timer_irq_init(void)
{
irq_initialize(&gxemul_timer_irq);
gxemul_timer_irq.devno = device_assign_devno();
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
gxemul_timer_irq.claim = gxemul_timer_claim;
gxemul_timer_irq.handler = gxemul_timer_irq_handler;
 
irq_register(&gxemul_timer_irq);
}
 
 
/** Starts timer.
*
* Initiates regular timer interrupts after initializing
* corresponding interrupt handler.
*/
void gxemul_timer_irq_start(void)
{
gxemul_timer_irq_init();
gxemul_timer_start(GXEMUL_TIMER_FREQ);
}
 
/** Returns the size of emulated memory.
*
* @return Size in bytes.
*/
size_t gxemul_get_memory_size(void)
{
return *((int *) (GXEMUL_MP + GXEMUL_MP_MEMSIZE_OFFSET));
}
 
/** Prints a character.
*
* @param ch Character to be printed.
*/
void gxemul_debug_putc(char ch)
{
char *addr = 0;
if (!hw_map_init_called) {
addr = (char *) GXEMUL_KBD;
} else {
addr = (char *) gxemul_hw_map.videoram;
}
 
*(addr) = ch;
}
 
/** Stops gxemul. */
void gxemul_cpu_halt(void)
{
char * addr = 0;
if (!hw_map_init_called) {
addr = (char *) GXEMUL_KBD;
} else {
addr = (char *) gxemul_hw_map.videoram;
}
*(addr + GXEMUL_HALT_OFFSET) = '\0';
}
 
/** Gxemul specific interrupt exception handler.
*
* Determines sources of the interrupt from interrupt controller and
* calls high-level handlers for them.
*
* @param exc_no Interrupt exception number.
* @param istate Saved processor state.
*/
void gxemul_irq_exception(int exc_no, istate_t *istate)
{
uint32_t sources = gxemul_irqc_get_sources();
int i;
for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq, irq->arg);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
dprintf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
/** Returns address of framebuffer device.
*
* @return Address of framebuffer device.
*/
uintptr_t gxemul_get_fb_address(void)
{
return (uintptr_t) GXEMUL_FB;
}
 
/*
* GXEMUL specific frame initialization
*/
void gxemul_frame_init(void)
{
}
/** @}
*/
/branches/arm/kernel/arch/arm32/src/cpu/cpu.c
36,7 → 36,7
#include <arch/cpu.h>
#include <cpu.h>
#include <arch.h>
#include <print.h>
#include <print.h>
 
/** Number of indexes left out in the #imp_data array */
#define IMP_DATA_START_OFFSET 0x40
82,10 → 82,10
{
uint32_t ident;
asm volatile (
"mrc p15, 0, %0, c0, c0, 0\n"
: "=r" (ident)
"mrc p15, 0, %[ident], c0, c0, 0\n"
: [ident] "=r" (ident)
);
 
cpu->imp_num = ident >> 24;
cpu->variant_num = (ident << 8) >> 28;
cpu->arch_num = (ident << 12) >> 28;
/branches/arm/kernel/arch/arm32/src/userspace.c
90,12 → 90,11
 
/* set user mode, set registers, jump */
asm volatile (
"mov sp, %0 \n"
"msr spsr_c, %1 \n"
"ldmfd sp!, {r0-r12, sp, lr}^ \n"
"mov sp, %[ustate]\n"
"msr spsr_c, %[user_mode]\n"
"ldmfd sp!, {r0-r12, sp, lr}^\n"
"ldmfd sp!, {pc}^\n"
:
: "r" (&ustate), "r" (user_mode)
:: [ustate] "r" (&ustate), [user_mode] "r" (user_mode)
);
 
/* unreachable */
/branches/arm/kernel/arch/arm32/src/start.S
40,30 → 40,12
mrs r3, cpsr
bic r3, r3, #0x1f
orr r3, r3, #0x13
msr cpsr_c, r3
msr cpsr_c, r3
ldr sp, =temp_stack
 
cmp r2, #0
beq bootinfo_end
 
ldr r3, =bootinfo
 
bootinfo_loop:
ldr r4, [r1]
str r4, [r3]
 
add r1, r1, #4
add r3, r3, #4
add r2, r2, #-4
 
cmp r2, #0
bne bootinfo_loop
bootinfo_end:
 
bl arch_pre_main
 
bl main_bsp
 
.space TEMP_STACK_SIZE
74,4 → 56,3
 
supervisor_sp:
.space 4
 
/branches/arm/kernel/arch/arm32/_link.ld.in
1,15 → 1,16
/*
* ARM linker script
*
* ARM linker script
*
* kernel text
* kernel data
*
*
*/
 
#define KERNEL_LOAD_ADDRESS 0x80200000
 
OUTPUT_ARCH(arm)
ENTRY(kernel_image_start)
ENTRY(kernel_image_start)
 
 
SECTIONS {
. = KERNEL_LOAD_ADDRESS;
.text : {
19,29 → 20,29
}
.data : {
kdata_start = .;
*(.data); /* initialized data */
*(.data); /* initialized data */
hardcoded_ktext_size = .;
LONG(ktext_end - ktext_start);
LONG(ktext_end - ktext_start);
hardcoded_kdata_size = .;
LONG(kdata_end - kdata_start);
hardcoded_load_address = .;
LONG(KERNEL_LOAD_ADDRESS);
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
 
*(.bss); /* uninitialized static variables */
*(COMMON); /* global variables */
*(.rodata*);
*(.sdata);
*(.reginfo);
symbol_table = .;
*(symtab.*);
*(symtab.*);
}
.sbss : {
*(.sbss);
*(.scommon);
}
 
kdata_end = .;
 
/DISCARD/ : {
*(.mdebug*);
*(.pdr);
48,5 → 49,4
*(.comment);
*(.note);
}
 
}
/branches/arm/kernel/arch/amd64/include/byteorder.h
File deleted
/branches/arm/kernel/arch/amd64/include/types.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64
/** @addtogroup amd64
* @{
*/
/** @file
46,8 → 46,6
typedef unsigned long long uint64_t;
 
typedef uint64_t size_t;
typedef uint64_t count_t;
typedef uint64_t index_t;
 
typedef uint64_t uintptr_t;
typedef uint64_t pfn_t;
57,11 → 55,12
typedef uint64_t unative_t;
typedef int64_t native_t;
 
/**< Formats for uintptr_t, size_t, count_t and index_t */
typedef struct {
} fncptr_t;
 
/**< Formats for uintptr_t, size_t */
#define PRIp "llx"
#define PRIs "llu"
#define PRIc "llu"
#define PRIi "llu"
 
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */
#define PRId8 "d"
/branches/arm/kernel/arch/amd64/include/proc/task.h
40,7 → 40,7
 
typedef struct {
/** I/O Permission bitmap Generation counter. */
count_t iomapver;
size_t iomapver;
/** I/O Permission bitmap. */
bitmap_t iomap;
} task_arch_t;
/branches/arm/kernel/arch/amd64/include/mm/page.h
112,33 → 112,33
#define SET_PTL0_ADDRESS_ARCH(ptl0) \
(write_cr3((uintptr_t) (ptl0)))
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
set_pt_addr((pte_t *) (ptl0), (index_t) (i), a)
set_pt_addr((pte_t *) (ptl0), (size_t) (i), a)
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) \
set_pt_addr((pte_t *) (ptl1), (index_t) (i), a)
set_pt_addr((pte_t *) (ptl1), (size_t) (i), a)
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) \
set_pt_addr((pte_t *) (ptl2), (index_t) (i), a)
set_pt_addr((pte_t *) (ptl2), (size_t) (i), a)
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
set_pt_addr((pte_t *) (ptl3), (index_t) (i), a)
set_pt_addr((pte_t *) (ptl3), (size_t) (i), a)
 
/* Get PTE flags accessors for each level. */
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
get_pt_flags((pte_t *) (ptl0), (index_t) (i))
get_pt_flags((pte_t *) (ptl0), (size_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
get_pt_flags((pte_t *) (ptl1), (index_t) (i))
get_pt_flags((pte_t *) (ptl1), (size_t) (i))
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
get_pt_flags((pte_t *) (ptl2), (index_t) (i))
get_pt_flags((pte_t *) (ptl2), (size_t) (i))
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
get_pt_flags((pte_t *) (ptl3), (index_t) (i))
get_pt_flags((pte_t *) (ptl3), (size_t) (i))
 
/* Set PTE flags accessors for each level. */
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) \
set_pt_flags((pte_t *) (ptl1), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl1), (size_t) (i), (x))
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) \
set_pt_flags((pte_t *) (ptl2), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl2), (size_t) (i), (x))
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
 
/* Macros for querying the last-level PTE entries. */
#define PTE_VALID_ARCH(p) \
176,7 → 176,7
*/
#define PFERR_CODE_ID (1 << 4)
 
static inline int get_pt_flags(pte_t *pt, index_t i)
static inline int get_pt_flags(pte_t *pt, size_t i)
{
pte_t *p = &pt[i];
189,7 → 189,7
p->global << PAGE_GLOBAL_SHIFT);
}
 
static inline void set_pt_addr(pte_t *pt, index_t i, uintptr_t a)
static inline void set_pt_addr(pte_t *pt, size_t i, uintptr_t a)
{
pte_t *p = &pt[i];
 
197,7 → 197,7
p->addr_32_51 = a >> 32;
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
{
pte_t *p = &pt[i];
/branches/arm/kernel/arch/amd64/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64mm
/** @addtogroup amd64mm
* @{
*/
/** @file
39,8 → 39,8
#include <arch/types.h>
#endif /* __ASM__ */
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifndef __ASM__
extern uintptr_t last_frame;
/branches/arm/kernel/arch/amd64/include/mm/tlb.h
35,9 → 35,6
#ifndef KERN_amd64_TLB_H_
#define KERN_amd64_TLB_H_
 
#define tlb_arch_init()
#define tlb_print()
 
#endif
 
/** @}
/branches/arm/kernel/arch/amd64/include/cpu.h
35,9 → 35,9
#ifndef KERN_amd64_CPU_H_
#define KERN_amd64_CPU_H_
 
#define RFLAGS_IF (1 << 9)
#define RFLAGS_DF (1 << 10)
#define RFLAGS_RF (1 << 16)
#define RFLAGS_IF (1 << 9)
#define RFLAGS_DF (1 << 10)
#define RFLAGS_RF (1 << 16)
 
#define EFER_MSR_NUM 0xc0000080
#define AMD_SCE_FLAG 0
62,17 → 62,15
int family;
int model;
int stepping;
struct tss *tss;
tss_t *tss;
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
size_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
} cpu_arch_t;
 
struct star_msr {
};
 
struct lstar_msr {
};
 
extern void set_efer_flag(int flag);
/branches/arm/kernel/arch/amd64/include/atomic.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64
/** @addtogroup amd64
* @{
*/
/** @file
41,17 → 41,29
 
static inline void atomic_inc(atomic_t *val) {
#ifdef CONFIG_SMP
asm volatile ("lock incq %0\n" : "+m" (val->count));
asm volatile (
"lock incq %[count]\n"
: [count] "+m" (val->count)
);
#else
asm volatile ("incq %0\n" : "+m" (val->count));
asm volatile (
"incq %[count]\n"
: [count] "+m" (val->count)
);
#endif /* CONFIG_SMP */
}
 
static inline void atomic_dec(atomic_t *val) {
#ifdef CONFIG_SMP
asm volatile ("lock decq %0\n" : "+m" (val->count));
asm volatile (
"lock decq %[count]\n"
: [count] "+m" (val->count)
);
#else
asm volatile ("decq %0\n" : "+m" (val->count));
asm volatile (
"decq %[count]\n"
: [count] "+m" (val->count)
);
#endif /* CONFIG_SMP */
}
 
58,12 → 70,12
static inline long atomic_postinc(atomic_t *val)
{
long r = 1;
 
asm volatile (
"lock xaddq %1, %0\n"
: "+m" (val->count), "+r" (r)
"lock xaddq %[r], %[count]\n"
: [count] "+m" (val->count), [r] "+r" (r)
);
 
return r;
}
 
72,23 → 84,23
long r = -1;
asm volatile (
"lock xaddq %1, %0\n"
: "+m" (val->count), "+r" (r)
"lock xaddq %[r], %[count]\n"
: [count] "+m" (val->count), [r] "+r" (r)
);
return r;
}
 
#define atomic_preinc(val) (atomic_postinc(val) + 1)
#define atomic_predec(val) (atomic_postdec(val) - 1)
#define atomic_preinc(val) (atomic_postinc(val) + 1)
#define atomic_predec(val) (atomic_postdec(val) - 1)
 
static inline uint64_t test_and_set(atomic_t *val) {
uint64_t v;
asm volatile (
"movq $1, %0\n"
"xchgq %0, %1\n"
: "=r" (v), "+m" (val->count)
"movq $1, %[v]\n"
"xchgq %[v], %[count]\n"
: [v] "=r" (v), [count] "+m" (val->count)
);
return v;
99,22 → 111,20
static inline void atomic_lock_arch(atomic_t *val)
{
uint64_t tmp;
 
preemption_disable();
asm volatile (
"0:\n"
#ifdef CONFIG_HT
"pause\n"
#endif
"mov %0, %1\n"
"testq %1, %1\n"
"mov %[count], %[tmp]\n"
"testq %[tmp], %[tmp]\n"
"jnz 0b\n" /* lightweight looping on locked spinlock */
"incq %1\n" /* now use the atomic operation */
"xchgq %0, %1\n"
"testq %1, %1\n"
"incq %[tmp]\n" /* now use the atomic operation */
"xchgq %[count], %[tmp]\n"
"testq %[tmp], %[tmp]\n"
"jnz 0b\n"
: "+m" (val->count), "=&r" (tmp)
: [count] "+m" (val->count), [tmp] "=&r" (tmp)
);
/*
* Prevent critical section code from bleeding out this way up.
/branches/arm/kernel/arch/amd64/include/cpuid.h
35,14 → 35,15
#ifndef KERN_amd64_CPUID_H_
#define KERN_amd64_CPUID_H_
 
#define AMD_CPUID_EXTENDED 0x80000001
#define AMD_EXT_NOEXECUTE 20
#define AMD_EXT_LONG_MODE 29
#define AMD_CPUID_EXTENDED 0x80000001
#define AMD_EXT_NOEXECUTE 20
#define AMD_EXT_LONG_MODE 29
 
#define INTEL_CPUID_STANDARD 0x00000001
#define INTEL_CPUID_EXTENDED 0x80000000
#define INTEL_SSE2 26
#define INTEL_FXSAVE 24
#define INTEL_CPUID_LEVEL 0x00000000
#define INTEL_CPUID_STANDARD 0x00000001
#define INTEL_CPUID_EXTENDED 0x80000000
#define INTEL_SSE2 26
#define INTEL_FXSAVE 24
 
#ifndef __ASM__
 
/branches/arm/kernel/arch/amd64/include/pm.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64
/** @addtogroup amd64
* @{
*/
/** @file
36,63 → 36,60
#define KERN_amd64_PM_H_
 
#ifndef __ASM__
# include <arch/types.h>
# include <arch/context.h>
#include <arch/types.h>
#include <arch/context.h>
#endif
 
#define IDT_ITEMS 64
#define GDT_ITEMS 8
#define IDT_ITEMS 64
#define GDT_ITEMS 8
 
 
#define NULL_DES 0
/* Warning: Do not reorder next items, unless you look into syscall.c!!! */
#define KTEXT_DES 1
#define KDATA_DES 2
#define UDATA_DES 3
#define UTEXT_DES 4
#define KTEXT32_DES 5
/* EndOfWarning */
#define TSS_DES 6
#define NULL_DES 0
/* Warning: Do not reorder the following items, unless you look into syscall.c! */
#define KTEXT_DES 1
#define KDATA_DES 2
#define UDATA_DES 3
#define UTEXT_DES 4
#define KTEXT32_DES 5
/* End of warning */
#define TSS_DES 6
 
 
 
#ifdef CONFIG_FB
 
#define VESA_INIT_DES 8
#define VESA_INIT_SEGMENT 0x8000
#undef GDT_ITEMS
#define GDT_ITEMS 9
#define VESA_INIT_DES 8
#define VESA_INIT_SEGMENT 0x8000
 
#endif /*CONFIG_FB*/
#undef GDT_ITEMS
#define GDT_ITEMS 9
 
#endif /* CONFIG_FB */
 
#define gdtselector(des) ((des) << 3)
#define idtselector(des) ((des) << 4)
 
#define gdtselector(des) ((des) << 3)
#define idtselector(des) ((des) << 4)
#define PL_KERNEL 0
#define PL_USER 3
 
#define PL_KERNEL 0
#define PL_USER 3
#define AR_PRESENT ( 1 << 7)
#define AR_DATA (2 << 3)
#define AR_CODE (3 << 3)
#define AR_WRITABLE (1 << 1)
#define AR_READABLE (1 << 1)
#define AR_TSS (0x09)
#define AR_INTERRUPT (0x0e)
#define AR_TRAP (0x0f)
 
#define AR_PRESENT (1<<7)
#define AR_DATA (2<<3)
#define AR_CODE (3<<3)
#define AR_WRITABLE (1<<1)
#define AR_READABLE (1<<1)
#define AR_TSS (0x9)
#define AR_INTERRUPT (0xe)
#define AR_TRAP (0xf)
#define DPL_KERNEL (PL_KERNEL << 5)
#define DPL_USER (PL_USER << 5)
 
#define DPL_KERNEL (PL_KERNEL<<5)
#define DPL_USER (PL_USER<<5)
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */
 
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16*1024+1) /* 16K for bitmap + 1 terminating byte for convenience */
#define IO_PORTS (64 * 1024)
 
#define IO_PORTS (64*1024)
 
#ifndef __ASM__
 
struct descriptor {
typedef struct {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
103,10 → 100,9
unsigned special: 1;
unsigned granularity : 1;
unsigned base_24_31: 8;
} __attribute__ ((packed));
typedef struct descriptor descriptor_t;
} __attribute__ ((packed)) descriptor_t;
 
struct tss_descriptor {
typedef struct {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
121,10 → 117,9
unsigned base_24_31: 8;
unsigned base_32_63 : 32;
unsigned : 32;
} __attribute__ ((packed));
typedef struct tss_descriptor tss_descriptor_t;
} __attribute__ ((packed)) tss_descriptor_t;
 
struct idescriptor {
typedef struct {
unsigned offset_0_15: 16;
unsigned selector: 16;
unsigned ist:3;
135,22 → 130,19
unsigned offset_16_31: 16;
unsigned offset_32_63: 32;
unsigned : 32;
} __attribute__ ((packed));
typedef struct idescriptor idescriptor_t;
} __attribute__ ((packed)) idescriptor_t;
 
struct ptr_16_64 {
typedef struct {
uint16_t limit;
uint64_t base;
} __attribute__ ((packed));
typedef struct ptr_16_64 ptr_16_64_t;
} __attribute__ ((packed)) ptr_16_64_t;
 
struct ptr_16_32 {
typedef struct {
uint16_t limit;
uint32_t base;
} __attribute__ ((packed));
typedef struct ptr_16_32 ptr_16_32_t;
} __attribute__ ((packed)) ptr_16_32_t;
 
struct tss {
typedef struct {
uint32_t reserve1;
uint64_t rsp0;
uint64_t rsp1;
167,8 → 159,7
uint16_t reserve4;
uint16_t iomap_base;
uint8_t iomap[TSS_IOMAP_SIZE];
} __attribute__ ((packed));
typedef struct tss tss_t;
} __attribute__ ((packed)) tss_t;
 
extern tss_t *tss_p;
 
/branches/arm/kernel/arch/amd64/include/asm.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64
/** @addtogroup amd64
* @{
*/
/** @file
36,6 → 36,8
#define KERN_amd64_ASM_H_
 
#include <config.h>
#include <arch/types.h>
#include <typedefs.h>
 
extern void asm_delay_loop(uint32_t t);
extern void asm_fake_loop(uint32_t t);
45,12 → 47,17
* Return the base address of the current stack.
* The stack is assumed to be STACK_SIZE bytes long.
* The stack must start on page boundary.
*
*/
static inline uintptr_t get_stack_base(void)
{
uintptr_t v;
asm volatile ("andq %%rsp, %0\n" : "=r" (v) : "0" (~((uint64_t)STACK_SIZE-1)));
asm volatile (
"andq %%rsp, %[v]\n"
: [v] "=r" (v)
: "0" (~((uint64_t) STACK_SIZE-1))
);
return v;
}
62,7 → 69,11
 
static inline void cpu_halt(void)
{
asm volatile ("hlt\n");
asm volatile (
"0:\n"
" hlt\n"
" jmp 0b\n"
);
}
 
 
72,15 → 83,63
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint8_t inb(uint16_t port)
static inline uint8_t pio_read_8(ioport8_t *port)
{
uint8_t val;
asm volatile (
"inb %w[port], %b[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port));
/** Word from port
*
* Get word from port
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint16_t pio_read_16(ioport16_t *port)
{
uint16_t val;
asm volatile (
"inw %w[port], %w[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
/** Double word from port
*
* Get double word from port
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint32_t pio_read_32(ioport32_t *port)
{
uint32_t val;
asm volatile (
"inl %w[port], %[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
/** Byte to port
*
* Output byte to port
87,12 → 146,48
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void outb(uint16_t port, uint8_t val)
static inline void pio_write_8(ioport8_t *port, uint8_t val)
{
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port));
asm volatile (
"outb %b[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Word to port
*
* Output word to port
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void pio_write_16(ioport16_t *port, uint16_t val)
{
asm volatile (
"outw %w[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Double word to port
*
* Output double word to port
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void pio_write_32(ioport32_t *port, uint32_t val)
{
asm volatile (
"outl %[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Swap Hidden part of GS register with visible one */
static inline void swapgs(void)
{
105,15 → 200,18
* value of EFLAGS.
*
* @return Old interrupt priority level.
*
*/
static inline ipl_t interrupts_enable(void) {
ipl_t v;
__asm__ volatile (
asm volatile (
"pushfq\n"
"popq %0\n"
"popq %[v]\n"
"sti\n"
: "=r" (v)
: [v] "=r" (v)
);
return v;
}
 
123,15 → 221,18
* value of EFLAGS.
*
* @return Old interrupt priority level.
*
*/
static inline ipl_t interrupts_disable(void) {
ipl_t v;
__asm__ volatile (
asm volatile (
"pushfq\n"
"popq %0\n"
"popq %[v]\n"
"cli\n"
: "=r" (v)
);
: [v] "=r" (v)
);
return v;
}
 
140,13 → 241,14
* Restore EFLAGS.
*
* @param ipl Saved interrupt priority level.
*
*/
static inline void interrupts_restore(ipl_t ipl) {
__asm__ volatile (
"pushq %0\n"
asm volatile (
"pushq %[ipl]\n"
"popfq\n"
: : "r" (ipl)
);
:: [ipl] "r" (ipl)
);
}
 
/** Return interrupt priority level.
154,14 → 256,17
* Return EFLAFS.
*
* @return Current interrupt priority level.
*
*/
static inline ipl_t interrupts_read(void) {
ipl_t v;
__asm__ volatile (
asm volatile (
"pushfq\n"
"popq %0\n"
: "=r" (v)
"popq %[v]\n"
: [v] "=r" (v)
);
return v;
}
 
168,21 → 273,25
/** Write to MSR */
static inline void write_msr(uint32_t msr, uint64_t value)
{
__asm__ volatile (
"wrmsr;" : : "c" (msr),
"a" ((uint32_t)(value)),
"d" ((uint32_t)(value >> 32))
);
asm volatile (
"wrmsr\n"
:: "c" (msr),
"a" ((uint32_t) (value)),
"d" ((uint32_t) (value >> 32))
);
}
 
static inline unative_t read_msr(uint32_t msr)
{
uint32_t ax, dx;
 
__asm__ volatile (
"rdmsr;" : "=a"(ax), "=d"(dx) : "c" (msr)
);
return ((uint64_t)dx << 32) | ax;
asm volatile (
"rdmsr\n"
: "=a" (ax), "=d" (dx)
: "c" (msr)
);
return ((uint64_t) dx << 32) | ax;
}
 
 
189,29 → 298,29
/** Enable local APIC
*
* Enable local APIC in MSR.
*
*/
static inline void enable_l_apic_in_msr()
{
__asm__ volatile (
asm volatile (
"movl $0x1b, %%ecx\n"
"rdmsr\n"
"orl $(1<<11),%%eax\n"
"orl $(1 << 11),%%eax\n"
"orl $(0xfee00000),%%eax\n"
"wrmsr\n"
:
:
:"%eax","%ecx","%edx"
);
::: "%eax","%ecx","%edx"
);
}
 
static inline uintptr_t * get_ip()
{
uintptr_t *ip;
 
__asm__ volatile (
"mov %%rip, %0"
: "=r" (ip)
);
asm volatile (
"mov %%rip, %[ip]"
: [ip] "=r" (ip)
);
return ip;
}
 
218,59 → 327,84
/** Invalidate TLB Entry.
*
* @param addr Address on a page whose TLB entry is to be invalidated.
*
*/
static inline void invlpg(uintptr_t addr)
{
__asm__ volatile ("invlpg %0\n" :: "m" (*((unative_t *)addr)));
asm volatile (
"invlpg %[addr]\n"
:: [addr] "m" (*((unative_t *) addr))
);
}
 
/** Load GDTR register from memory.
*
* @param gdtr_reg Address of memory from where to load GDTR.
*
*/
static inline void gdtr_load(struct ptr_16_64 *gdtr_reg)
static inline void gdtr_load(ptr_16_64_t *gdtr_reg)
{
__asm__ volatile ("lgdtq %0\n" : : "m" (*gdtr_reg));
asm volatile (
"lgdtq %[gdtr_reg]\n"
:: [gdtr_reg] "m" (*gdtr_reg)
);
}
 
/** Store GDTR register to memory.
*
* @param gdtr_reg Address of memory to where to load GDTR.
*
*/
static inline void gdtr_store(struct ptr_16_64 *gdtr_reg)
static inline void gdtr_store(ptr_16_64_t *gdtr_reg)
{
__asm__ volatile ("sgdtq %0\n" : : "m" (*gdtr_reg));
asm volatile (
"sgdtq %[gdtr_reg]\n"
:: [gdtr_reg] "m" (*gdtr_reg)
);
}
 
/** Load IDTR register from memory.
*
* @param idtr_reg Address of memory from where to load IDTR.
*
*/
static inline void idtr_load(struct ptr_16_64 *idtr_reg)
static inline void idtr_load(ptr_16_64_t *idtr_reg)
{
__asm__ volatile ("lidtq %0\n" : : "m" (*idtr_reg));
asm volatile (
"lidtq %[idtr_reg]\n"
:: [idtr_reg] "m" (*idtr_reg));
}
 
/** Load TR from descriptor table.
*
* @param sel Selector specifying descriptor of TSS segment.
*
*/
static inline void tr_load(uint16_t sel)
{
__asm__ volatile ("ltr %0" : : "r" (sel));
asm volatile (
"ltr %[sel]"
:: [sel] "r" (sel)
);
}
 
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
{ \
unative_t res; \
__asm__ volatile ("movq %%" #reg ", %0" : "=r" (res) ); \
return res; \
}
{ \
unative_t res; \
asm volatile ( \
"movq %%" #reg ", %[res]" \
: [res] "=r" (res) \
); \
return res; \
}
 
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
{ \
__asm__ volatile ("movq %0, %%" #reg : : "r" (regn)); \
}
{ \
asm volatile ( \
"movq %[regn], %%" #reg \
:: [regn] "r" (regn) \
); \
}
 
GEN_READ_REG(cr0)
GEN_READ_REG(cr2)
/branches/arm/kernel/arch/amd64/include/boot/boot.h
42,8 → 42,17
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
#define MULTIBOOT_HEADER_FLAGS 0x00010003
 
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002
#ifndef __ASM__
 
#ifdef CONFIG_SMP
 
/* This is only a symbol so the type is dummy. Obtain the value using &. */
extern int _hardcoded_unmapped_size;
 
#endif /* CONFIG_SMP */
 
#endif /* __ASM__ */
 
#endif
 
/** @}
/branches/arm/kernel/arch/amd64/include/arch.h
35,6 → 35,10
#ifndef KERN_amd64_ARCH_H_
#define KERN_amd64_ARCH_H_
 
#include <genarch/multiboot/multiboot.h>
 
extern void arch_pre_main(uint32_t, const multiboot_info_t *);
 
#endif
 
/** @}
/branches/arm/kernel/arch/amd64/include/interrupt.h
71,7 → 71,6
/** This is passed to interrupt handlers */
typedef struct {
uint64_t rax;
uint64_t rbx;
uint64_t rcx;
uint64_t rdx;
uint64_t rsi;
80,11 → 79,6
uint64_t r9;
uint64_t r10;
uint64_t r11;
uint64_t r12;
uint64_t r13;
uint64_t r14;
uint64_t r15;
uint64_t rbp;
uint64_t error_word;
uint64_t rip;
uint64_t cs;
/branches/arm/kernel/arch/amd64/include/drivers/i8254.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/include/drivers/ega.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/include/drivers/vesa.h
File deleted
/branches/arm/kernel/arch/amd64/include/drivers/i8259.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/include/drivers/i8042.h
File deleted
\ No newline at end of file
Property changes:
Deleted: svn:special
-*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/include/drivers
0,0 → 1,0
link ../../ia32/include/drivers
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/include/syscall.h
35,8 → 35,6
#ifndef KERN_amd64_SYSCALL_H_
#define KERN_amd64_SYSCALL_H_
 
#include <arch/types.h>
 
extern void syscall_setup_cpu(void);
 
#endif
/branches/arm/kernel/arch/amd64/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf64-x86-64
BFD_ARCH = i386:x86-64
BFD = binary
45,83 → 41,51
ICC_CFLAGS += $(CMN1)
SUNCC_CFLAGS += -m64 -xmodel=kernel
 
DEFS += -DMACHINE=$(MACHINE) -D__64_BITS__
BITS = 64
ENDIANESS = LE
 
## Accepted CPUs
#
 
ifeq ($(MACHINE),opteron)
ifeq ($(PROCESSOR),opteron)
CMN2 := -march=opteron
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xtarget=opteron
DEFS += -DFENCES=p4
endif
 
## Own configuration directives
#
 
CONFIG_ACPI = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with i8042 support.
#
 
CONFIG_I8042 = y
DEFS += -DCONFIG_I8042
 
## Accepted configuration directives
#
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
endif
ifeq ($(CONFIG_HT),y)
DEFS += -DCONFIG_HT
endif
 
ifeq ($(CONFIG_SIMICS_FIX),y)
DEFS += -DCONFIG_SIMICS_FIX
endif
 
ARCH_SOURCES = \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/boot/memmap.c \
arch/$(ARCH)/src/pm.c \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/ega.c \
arch/$(ARCH)/src/drivers/vesa.c \
arch/$(ARCH)/src/drivers/i8254.c \
arch/$(ARCH)/src/drivers/i8259.c \
arch/$(ARCH)/src/delay.S \
arch/$(ARCH)/src/amd64.c \
arch/$(ARCH)/src/bios/bios.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/asm_utils.S \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/proc/task.c \
arch/$(ARCH)/src/proc/thread.c \
arch/$(ARCH)/src/userspace.c \
arch/$(ARCH)/src/syscall.c \
arch/$(ARCH)/src/debugger.c
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/boot/boot.S \
arch/$(KARCH)/src/boot/memmap.c \
arch/$(KARCH)/src/pm.c \
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/drivers/vesa.c \
arch/$(KARCH)/src/drivers/i8254.c \
arch/$(KARCH)/src/drivers/i8259.c \
arch/$(KARCH)/src/delay.S \
arch/$(KARCH)/src/amd64.c \
arch/$(KARCH)/src/bios/bios.c \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/asm_utils.S \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/proc/task.c \
arch/$(KARCH)/src/proc/thread.c \
arch/$(KARCH)/src/userspace.c \
arch/$(KARCH)/src/syscall.c \
arch/$(KARCH)/src/debugger.c
 
ifeq ($(CONFIG_SMP),y)
ARCH_SOURCES += \
arch/$(ARCH)/src/smp/ap.S \
arch/$(ARCH)/src/smp/apic.c \
arch/$(ARCH)/src/smp/ipi.c \
arch/$(ARCH)/src/smp/mps.c \
arch/$(ARCH)/src/smp/smp.c
arch/$(KARCH)/src/smp/ap.S \
arch/$(KARCH)/src/smp/apic.c \
arch/$(KARCH)/src/smp/ipi.c \
arch/$(KARCH)/src/smp/mps.c \
arch/$(KARCH)/src/smp/smp.c
endif
/branches/arm/kernel/arch/amd64/src/ddi/ddi.c
56,16 → 56,16
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
count_t bits;
 
size_t bits;
bits = ioaddr + size;
if (bits > IO_PORTS)
return ENOENT;
 
if (task->arch.iomap.bits < bits) {
bitmap_t oldiomap;
uint8_t *newmap;
/*
* The I/O permission bitmap is too small and needs to be grown.
*/
77,17 → 77,17
bitmap_initialize(&oldiomap, task->arch.iomap.map,
task->arch.iomap.bits);
bitmap_initialize(&task->arch.iomap, newmap, bits);
 
/*
* Mark the new range inaccessible.
*/
bitmap_set_range(&task->arch.iomap, oldiomap.bits,
bits - oldiomap.bits);
 
/*
* In case there really existed smaller iomap,
* copy its contents and deallocate it.
*/
*/
if (oldiomap.bits) {
bitmap_copy(&task->arch.iomap, &oldiomap,
oldiomap.bits);
94,17 → 94,17
free(oldiomap.map);
}
}
 
/*
* Enable the range and we are done.
*/
bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
 
bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size);
/*
* Increment I/O Permission bitmap generation counter.
*/
task->arch.iomapver++;
 
return 0;
}
 
117,12 → 117,12
*/
void io_perm_bitmap_install(void)
{
count_t bits;
size_t bits;
ptr_16_64_t cpugdtr;
descriptor_t *gdt_p;
tss_descriptor_t *tss_desc;
count_t ver;
 
size_t ver;
/* First, copy the I/O Permission Bitmap. */
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
140,7 → 140,7
bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8);
}
spinlock_unlock(&TASK->lock);
 
/*
* Second, adjust TSS segment limit.
* Take the extra ending byte will all bits set into account.
151,10 → 151,10
gdtr_load(&cpugdtr);
/*
* Before we load new TSS limit, the current TSS descriptor
* type must be changed to describe inactive TSS.
*/
tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];
* Before we load new TSS limit, the current TSS descriptor
* type must be changed to describe inactive TSS.
*/
tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];
tss_desc->type = AR_TSS;
tr_load(gdtselector(TSS_DES));
/branches/arm/kernel/arch/amd64/src/interrupt.c
43,7 → 43,6
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch.h>
#include <symtab.h>
#include <arch/asm.h>
#include <proc/scheduler.h>
#include <proc/thread.h>
52,6 → 51,7
#include <arch/ddi/ddi.h>
#include <interrupt.h>
#include <ddi/irq.h>
#include <symtab.h>
 
/*
* Interrupt and exception dispatching.
64,10 → 64,8
void decode_istate(int n, istate_t *istate)
{
char *symbol;
/* uint64_t *x = &istate->stack[0]; */
 
if (!(symbol = get_symtab_entry(istate->rip)))
symbol = "";
symbol = symtab_fmt_name_lookup(istate->rip);
 
printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n", n, __func__);
printf("%%rip: %#llx (%s)\n", istate->rip, symbol);
80,12 → 78,6
istate->rdi, istate->r8);
printf("%%r9=%#llx, %%r10=%#llx, %%r11=%#llx\n", istate->r9,
istate->r10, istate->r11);
#ifdef CONFIG_DEBUG_ALLREGS
printf("%%r12=%#llx, %%r13=%#llx, %%r14=%#llx\n", istate->r12,
istate->r13, istate->r14);
printf("%%r15=%#llx, %%rbx=%#llx, %%rbp=%#llx\n", istate->r15,
istate->rbx, &istate->rbp);
#endif
printf("%%rsp=%#llx\n", &istate->stack[0]);
}
 
94,15 → 86,15
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(n, istate);
panic("unserviced interrupt\n");
panic("Unserviced interrupt.");
}
 
/** General Protection Fault. */
109,7 → 101,7
static void gp_fault(int n, istate_t *istate)
{
if (TASK) {
count_t ver;
size_t ver;
 
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
126,35 → 118,37
io_perm_bitmap_install();
return;
}
fault_if_from_uspace(istate, "general protection fault");
fault_if_from_uspace(istate, "General protection fault.");
}
 
decode_istate(n, istate);
panic("general protection fault\n");
panic("General protection fault.");
}
 
static void ss_fault(int n, istate_t *istate)
{
fault_if_from_uspace(istate, "stack fault");
fault_if_from_uspace(istate, "Stack fault.");
decode_istate(n, istate);
panic("stack fault\n");
panic("Stack fault.");
}
 
static void nm_fault(int n, istate_t *istate)
{
#ifdef CONFIG_FPU_LAZY
#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
}
 
#ifdef CONFIG_SMP
static void tlb_shootdown_ipi(int n, istate_t *istate)
{
trap_virtual_eoi();
tlb_shootdown_ipi_recv();
}
#endif
 
/** Handler of IRQ exceptions */
static void irq_interrupt(int n, istate_t *istate)
177,7 → 171,7
trap_virtual_eoi();
ack = true;
}
irq->handler(irq, irq->arg);
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/*
221,7 → 215,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)
229,7 → 223,7
if (disable_irqs_function)
disable_irqs_function(irqmask);
else
panic("no disable_irqs_function\n");
panic("No disable_irqs_function.");
}
 
/** @}
/branches/arm/kernel/arch/amd64/src/amd64.c
39,11 → 39,15
#include <config.h>
 
#include <proc/thread.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>
#include <arch/boot/boot.h>
 
#ifdef CONFIG_SMP
#include <arch/smp/apic.h>
61,9 → 65,8
#include <syscall/syscall.h>
#include <console/console.h>
#include <ddi/irq.h>
#include <ddi/device.h>
#include <sysinfo/sysinfo.h>
 
 
/** Disable I/O on non-privileged levels
*
* Clean IOPL(12,13) and NT(14) flags in EFLAGS register
70,15 → 73,13
*/
static void clean_IOPL_NT_flags(void)
{
asm (
asm volatile (
"pushfq\n"
"pop %%rax\n"
"and $~(0x7000), %%rax\n"
"pushq %%rax\n"
"popfq\n"
:
:
: "%rax"
::: "%rax"
);
}
 
88,16 → 89,31
*/
static void clean_AM_flag(void)
{
asm (
asm volatile (
"mov %%cr0, %%rax\n"
"and $~(0x40000), %%rax\n"
"mov %%rax, %%cr0\n"
:
:
: "%rax"
::: "%rax"
);
}
 
/** Perform amd64-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)
{
/* Enable no-execute pages */
133,13 → 149,17
/* hard clock */
i8254_init();
#ifdef CONFIG_FB
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();
172,8 → 192,33
 
void arch_post_smp_init(void)
{
/* keyboard controller */
i8042_init(device_assign_devno(), IRQ_KBD, device_assign_devno(), IRQ_MOUSE);
#ifdef CONFIG_PC_KBD
/*
* Initialize the i8042 controller. Then initialize the keyboard
* module and connect it to i8042. Enable keyboard interrupts.
*/
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
if (i8042_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
i8042_wire(i8042_instance, kbrd);
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)
208,15 → 253,45
*/
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;
}
 
void arch_reboot(void)
{
#ifdef CONFIG_PC_KBD
i8042_cpu_reset((i8042_t *) I8042_BASE);
#endif
}
 
/** @}
*/
/branches/arm/kernel/arch/amd64/src/pm.c
137,8 → 137,8
 
void gdt_tss_setlimit(descriptor_t *d, uint32_t limit)
{
struct tss_descriptor *td = (tss_descriptor_t *) d;
 
tss_descriptor_t *td = (tss_descriptor_t *) d;
td->limit_0_15 = limit & 0xffff;
td->limit_16_19 = (limit >> 16) & 0xf;
}
185,14 → 185,14
*/
void pm_init(void)
{
descriptor_t *gdt_p = (struct descriptor *) gdtr.base;
descriptor_t *gdt_p = (descriptor_t *) gdtr.base;
tss_descriptor_t *tss_desc;
 
/*
* Each CPU has its private GDT and TSS.
* All CPUs share one IDT.
*/
 
if (config.cpu_active == 1) {
idt_init();
/*
200,20 → 200,19
* the heap hasn't been initialized so far.
*/
tss_p = &tss;
}
else {
} else {
/* We are going to use malloc, which may return
* non boot-mapped pointer, initialize the CR3 register
* ahead of page_init */
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
 
tss_p = (struct tss *) malloc(sizeof(tss_t), FRAME_ATOMIC);
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);
 
tss_desc = (tss_descriptor_t *) (&gdt_p[TSS_DES]);
tss_desc->present = 1;
tss_desc->type = AR_TSS;
221,7 → 220,7
gdt_tss_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p);
gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1);
 
gdtr_load(&gdtr);
idtr_load(&idtr);
/*
231,24 → 230,5
tr_load(gdtselector(TSS_DES));
}
 
/* Reboot the machine by initiating
* a triple fault
*/
void arch_reboot(void)
{
preemption_disable();
ipl_t ipl = interrupts_disable();
memsetb(idt, sizeof(idt), 0);
idtr_load(&idtr);
interrupts_restore(ipl);
asm volatile (
"int $0x03\n"
"cli\n"
"hlt\n"
);
}
 
/** @}
*/
/branches/arm/kernel/arch/amd64/src/debugger.c
35,7 → 35,6
#include <arch/debugger.h>
#include <console/kconsole.h>
#include <console/cmd.h>
#include <symtab.h>
#include <print.h>
#include <panic.h>
#include <interrupt.h>
44,6 → 43,7
#include <debug.h>
#include <func.h>
#include <smp/ipi.h>
#include <symtab.h>
 
typedef struct {
uintptr_t address; /**< Breakpoint address */
54,6 → 54,8
static bpinfo_t breakpoints[BKPOINTS_MAX];
SPINLOCK_INITIALIZE(bkpoint_lock);
 
#ifdef CONFIG_KCONSOLE
 
static int cmd_print_breakpoints(cmd_arg_t *argv);
static cmd_info_t bkpts_info = {
.name = "bkpts",
62,8 → 64,6
.argc = 0,
};
 
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
 
static int cmd_del_breakpoint(cmd_arg_t *argv);
static cmd_arg_t del_argv = {
.type = ARG_TYPE_INT
99,44 → 99,8
.argv = &addw_argv
};
 
#endif
#endif /* CONFIG_KCONSOLE */
 
/** Print table of active breakpoints */
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
{
unsigned int i;
char *symbol;
 
#ifdef __32_BITS__
printf("# Count Address In symbol\n");
printf("-- ----- ---------- ---------\n");
#endif
 
#ifdef __64_BITS__
printf("# Count Address In symbol\n");
printf("-- ----- ------------------ ---------\n");
#endif
for (i = 0; i < BKPOINTS_MAX; i++)
if (breakpoints[i].address) {
symbol = get_symtab_entry(breakpoints[i].address);
 
#ifdef __32_BITS__
printf("%-2u %-5d %#10zx %s\n", i,
breakpoints[i].counter, breakpoints[i].address,
symbol);
#endif
 
#ifdef __64_BITS__
printf("%-2u %-5d %#18zx %s\n", i,
breakpoints[i].counter, breakpoints[i].address,
symbol);
#endif
 
}
return 1;
}
 
/* Setup DR register according to table */
static void setup_dr(int curidx)
{
237,16 → 201,16
 
/* Send IPI */
#ifdef CONFIG_SMP
// ipi_broadcast(VECTOR_DEBUG_IPI);
// ipi_broadcast(VECTOR_DEBUG_IPI);
#endif
 
return curidx;
}
 
#ifdef amd64
# define getip(x) ((x)->rip)
#ifdef __64_BITS__
#define getip(x) ((x)->rip)
#else
# define getip(x) ((x)->eip)
#define getip(x) ((x)->eip)
#endif
 
static void handle_exception(int slot, istate_t *istate)
265,12 → 229,15
*((unative_t *) breakpoints[slot].address));
}
}
printf("Reached breakpoint %d:%lx(%s)\n", slot, getip(istate),
get_symtab_entry(getip(istate)));
printf("***Type 'exit' to exit kconsole.\n");
atomic_set(&haltstate,1);
kconsole((void *) "debug");
atomic_set(&haltstate,0);
 
printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate),
symtab_fmt_name_lookup(getip(istate)));
 
#ifdef CONFIG_KCONSOLE
atomic_set(&haltstate, 1);
kconsole("debug", "Debug console ready.\n", false);
atomic_set(&haltstate, 0);
#endif
}
 
void breakpoint_del(int slot)
299,42 → 266,8
#endif
}
 
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
 
/** Remove breakpoint from table */
int cmd_del_breakpoint(cmd_arg_t *argv)
{
unative_t bpno = argv->intval;
if (bpno > BKPOINTS_MAX) {
printf("Invalid breakpoint number.\n");
return 0;
}
breakpoint_del(argv->intval);
return 1;
}
 
/** Add new breakpoint to table */
static int cmd_add_breakpoint(cmd_arg_t *argv)
{
int flags;
int id;
 
if (argv == &add_argv) {
flags = BKPOINT_INSTR;
} else { /* addwatchp */
flags = BKPOINT_WRITE;
}
printf("Adding breakpoint on address: %p\n", argv->intval);
id = breakpoint_add((void *)argv->intval, flags, -1);
if (id < 0)
printf("Add breakpoint failed.\n");
else
printf("Added breakpoint %d.\n", id);
return 1;
}
#endif
 
static void debug_exception(int n __attribute__((unused)), istate_t *istate)
{
unative_t dr6;
341,7 → 274,7
int i;
/* Set RF to restart the instruction */
#ifdef amd64
#ifdef __64_BITS__
istate->rflags |= RFLAGS_RF;
#else
istate->eflags |= EFLAGS_RF;
379,24 → 312,24
 
for (i = 0; i < BKPOINTS_MAX; i++)
breakpoints[i].address = NULL;
 
#ifdef CONFIG_KCONSOLE
cmd_initialize(&bkpts_info);
if (!cmd_register(&bkpts_info))
panic("could not register command %s\n", bkpts_info.name);
printf("Cannot register command %s\n", bkpts_info.name);
 
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
cmd_initialize(&delbkpt_info);
if (!cmd_register(&delbkpt_info))
panic("could not register command %s\n", delbkpt_info.name);
printf("Cannot register command %s\n", delbkpt_info.name);
 
cmd_initialize(&addbkpt_info);
if (!cmd_register(&addbkpt_info))
panic("could not register command %s\n", addbkpt_info.name);
printf("Cannot register command %s\n", addbkpt_info.name);
 
cmd_initialize(&addwatchp_info);
if (!cmd_register(&addwatchp_info))
panic("could not register command %s\n", addwatchp_info.name);
#endif
printf("Cannot register command %s\n", addwatchp_info.name);
#endif /* CONFIG_KCONSOLE */
exc_register(VECTOR_DEBUG, "debugger", debug_exception);
#ifdef CONFIG_SMP
404,5 → 337,77
#endif
}
 
#ifdef CONFIG_KCONSOLE
/** Print table of active breakpoints */
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused)))
{
unsigned int i;
char *symbol;
 
#ifdef __32_BITS__
printf("# Count Address In symbol\n");
printf("-- ----- ---------- ---------\n");
#endif
 
#ifdef __64_BITS__
printf("# Count Address In symbol\n");
printf("-- ----- ------------------ ---------\n");
#endif
for (i = 0; i < BKPOINTS_MAX; i++)
if (breakpoints[i].address) {
symbol = symtab_fmt_name_lookup(
breakpoints[i].address);
 
#ifdef __32_BITS__
printf("%-2u %-5d %#10zx %s\n", i,
breakpoints[i].counter, breakpoints[i].address,
symbol);
#endif
 
#ifdef __64_BITS__
printf("%-2u %-5d %#18zx %s\n", i,
breakpoints[i].counter, breakpoints[i].address,
symbol);
#endif
 
}
return 1;
}
 
/** Remove breakpoint from table */
int cmd_del_breakpoint(cmd_arg_t *argv)
{
unative_t bpno = argv->intval;
if (bpno > BKPOINTS_MAX) {
printf("Invalid breakpoint number.\n");
return 0;
}
breakpoint_del(argv->intval);
return 1;
}
 
/** Add new breakpoint to table */
static int cmd_add_breakpoint(cmd_arg_t *argv)
{
int flags;
int id;
 
if (argv == &add_argv) {
flags = BKPOINT_INSTR;
} else { /* addwatchp */
flags = BKPOINT_WRITE;
}
printf("Adding breakpoint on address: %p\n", argv->intval);
id = breakpoint_add((void *)argv->intval, flags, -1);
if (id < 0)
printf("Add breakpoint failed.\n");
else
printf("Added breakpoint %d.\n", id);
return 1;
}
#endif /* CONFIG_KCONSOLE */
 
/** @}
*/
/branches/arm/kernel/arch/amd64/src/boot/vesa_ret.inc
0,0 → 1,19
.code32
vesa_init_protected:
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds # kernel data + stack
movw %cx, %ss
#
# Simics seems to remove hidden part of GS on entering user mode
# when _visible_ part of GS does not point to user-mode segment.
#
movw $gdtselector(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
movl $START_STACK, %esp # initialize stack pointer
jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
/branches/arm/kernel/arch/amd64/src/boot/boot.S
1,4 → 1,4
 
#
# Copyright (c) 2005 Ondrej Palkovsky
# Copyright (c) 2006 Martin Decky
# Copyright (c) 2008 Jakub Jermar
37,7 → 37,7
#include <arch/cpuid.h>
 
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
 
.section K_TEXT_START, "ax"
 
.code32
46,7 → 46,7
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
55,15 → 55,19
 
multiboot_image_start:
cld
movl $START_STACK, %esp # initialize stack pointer
lgdtl bootstrap_gdtr # initialize Global Descriptor Table register
 
movl $START_STACK, %esp # initialize stack pointer
lgdtl bootstrap_gdtr # initialize Global Descriptor Table register
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds # kernel data + stack
movw %cx, %ds # kernel data + stack
movw %cx, %ss
#
# Simics seems to remove hidden part of GS on entering user mode
# when _visible_ part of GS does not point to user-mode segment
# when _visible_ part of GS does not point to user-mode segment.
#
movw $gdtselector(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
71,17 → 75,19
jmpl $gdtselector(KTEXT32_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
#
# Protected 32-bit. We want to reuse the code-seg descriptor,
# the Default operand size must not be 1 when entering long mode
# the Default operand size must not be 1 when entering long mode.
#
movl $(INTEL_CPUID_EXTENDED), %eax
cpuid
cmp $(INTEL_CPUID_EXTENDED), %eax
movl $(INTEL_CPUID_EXTENDED), %eax
cpuid
cmp $(INTEL_CPUID_EXTENDED), %eax
ja extended_cpuid_supported
movl $extended_cpuid_msg, %esi
jmp error_halt
90,11 → 96,11
movl $(AMD_CPUID_EXTENDED), %eax
cpuid
bt $(AMD_EXT_LONG_MODE), %edx
jc long_mode_supported
jc long_mode_supported
movl $long_mode_msg, %esi
jmp error_halt
 
long_mode_supported:
bt $(AMD_EXT_NOEXECUTE), %edx
108,7 → 114,7
movl $(INTEL_CPUID_STANDARD), %eax
cpuid
bt $(INTEL_FXSAVE), %edx
jc fx_supported
jc fx_supported
movl $fx_msg, %esi
jmp error_halt
116,59 → 122,43
fx_supported:
bt $(INTEL_SSE2), %edx
jc sse2_supported
jc sse2_supported
movl $sse2_msg, %esi
jmp error_halt
sse2_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
vesa_meeting_point:
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
#include "vesa_prot.inc"
 
#
# Enable 64-bit page translation entries - CR4.PAE = 1.
# Paging is not enabled until after long mode is enabled
# Paging is not enabled until after long mode is enabled.
#
movl %cr4, %eax
btsl $5, %eax
movl %eax, %cr4
 
# Set up paging tables
# set up paging tables
leal ptl_0, %eax
movl %eax, %cr3
# Enable long mode
# enable long mode
movl $EFER_MSR_NUM, %ecx # EFER MSR number
rdmsr # Read EFER
btsl $AMD_LME_FLAG, %eax # Set LME = 1
wrmsr # Write EFER
movl $EFER_MSR_NUM, %ecx # EFER MSR number
rdmsr # read EFER
btsl $AMD_LME_FLAG, %eax # set LME = 1
wrmsr # write EFER
# Enable paging to activate long mode (set CR0.PG = 1)
# enable paging to activate long mode (set CR0.PG = 1)
movl %cr0, %eax
btsl $31, %eax
movl %eax, %cr0
# At this point we are in compatibility mode
# at this point we are in compatibility mode
jmpl $gdtselector(KTEXT_DES), $start64
 
175,362 → 165,29
.code64
start64:
movq $(PA2KA(START_STACK)), %rsp
movl grub_eax, %eax
movl grub_ebx, %ebx
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature
je valid_boot
xorl %ecx, %ecx # no memory size or 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
xorq %rcx, %rcx
movq %rcx, init
jmp mods_end
mods_valid:
xorq %rcx, %rcx
movl 20(%ebx), %ecx # mbi->mods_count
movq %rcx, init
cmpl $0, %ecx
je mods_end
movl 24(%ebx), %esi # mbi->mods_addr
movq $init, %rdi
mods_loop:
xorq %rdx, %rdx
movl 0(%esi), %edx # mods->mod_start
movq $0xffff800000000000, %r10
addq %r10, %rdx
movq %rdx, 8(%rdi)
xorq %rdx, %rdx
movl 4(%esi), %edx
subl 0(%esi), %edx # mods->mod_end - mods->mod_start
movq %rdx, 16(%rdi)
addl $16, %esi
addq $16, %rdi
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
movq $e820table, %rdi
xorl %edx, %edx
mmap_loop:
cmpl $0, %ecx
jle mmap_end
movl 4(%esi), %eax # mmap->base_addr_low
movl %eax, (%rdi)
movl 8(%esi), %eax # mmap->base_addr_high
movl %eax, 4(%rdi)
movl 12(%esi), %eax # mmap->length_low
movl %eax, 8(%rdi)
movl 16(%esi), %eax # mmap->length_high
movl %eax, 12(%rdi)
movl 20(%esi), %eax # mmap->type
movl %eax, 16(%rdi)
movl (%esi), %eax # mmap->size
addl $0x4, %eax
addl %eax, %esi
subl %eax, %ecx
addq $MEMMAP_E820_RECORD_SIZE, %rdi
incl %edx
jmp mmap_loop
mmap_end:
mmap_invalid:
movl %edx, e820counter
invalid_boot:
# call arch_pre_main(grub_eax, grub_ebx)
xorq %rdi, %rdi
movl grub_eax, %edi
xorq %rsi, %rsi
movl grub_ebx, %esi
call arch_pre_main
#ifdef CONFIG_SMP
call main_bsp
# copy AP bootstrap routines below 1 MB
# not reached
movq $BOOT_OFFSET, %rsi
movq $AP_BOOT_OFFSET, %rdi
movq $_hardcoded_unmapped_size, %rcx
rep movsb
#endif
call main_bsp # never returns
cli
hlt
hlt0:
hlt
jmp hlt0
 
#ifdef CONFIG_FB
.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 $0x0000fffc, %esp
movl $0x0000fffc, %ebp
#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_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
 
#define CONFIG_VESA_BPP_a 255
 
#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 $gdtselector(KTEXT32_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 $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds # kernel data + stack
movw %cx, %ss
# Simics seems to remove hidden part of GS on entering user mode
# when _visible_ part of GS does not point to user-mode segment
movw $gdtselector(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
movl $START_STACK, %esp # initialize stack pointer
jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
.align 4
e_vesa_init:
#endif
 
# 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
538,7 → 195,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
547,7 → 204,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
554,7 → 213,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
561,11 → 220,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
573,7 → 232,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
580,17 → 239,20
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
cli
hlt
hlt1:
hlt
jmp hlt1
 
#include "vesa_real.inc"
 
.section K_INI_PTLS, "aw", @progbits
 
#
# Macro for generating initial page table contents.
# @param cnt Number of entries to generat. Must be multiple of 8.
# @param g Number of GB that will be added to the mapping.
# @param cnt Number of entries to generat. Must be multiple of 8.
# @param g Number of GB that will be added to the mapping.
#
.macro ptl2gen cnt g
.if \cnt
642,7 → 304,7
# Mapping of [0; 1G) at -2G
.quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
.fill 1, 8, 0
 
.align 4096
.global ptl_0
ptl_0:
/branches/arm/kernel/arch/amd64/src/boot/vesa_real.inc
0,0 → 1,0
link ../../../ia32/src/boot/vesa_real.inc
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/src/boot/vesa_prot.inc
0,0 → 1,0
link ../../../ia32/src/boot/vesa_prot.inc
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/kernel/arch/amd64/src/boot/memmap.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64mm
/** @addtogroup amd64mm
* @{
*/
/** @file
/branches/arm/kernel/arch/amd64/src/fpu_context.c
39,9 → 39,9
void fpu_context_save(fpu_context_t *fctx)
{
asm volatile (
"fxsave %0"
: "=m"(*fctx)
);
"fxsave %[fctx]\n"
: [fctx] "=m" (*fctx)
);
}
 
/** Restore FPU (mmx,sse) context using fxrstor instruction */
48,9 → 48,9
void fpu_context_restore(fpu_context_t *fctx)
{
asm volatile (
"fxrstor %0"
: "=m"(*fctx)
);
"fxrstor %[fctx]\n"
: [fctx] "=m" (*fctx)
);
}
 
void fpu_init()
57,7 → 57,7
{
/* TODO: Zero all SSE, MMX etc. registers */
asm volatile (
"fninit;"
"fninit\n"
);
}
 
/branches/arm/kernel/arch/amd64/src/cpu/cpu.c
77,21 → 77,19
void cpu_setup_fpu(void)
{
asm volatile (
"movq %%cr0, %%rax;"
"btsq $1, %%rax;" /* cr0.mp */
"btrq $2, %%rax;" /* cr0.em */
"movq %%rax, %%cr0;"
 
"movq %%cr4, %%rax;"
"bts $9, %%rax;" /* cr4.osfxsr */
"movq %%rax, %%cr4;"
:
:
:"%rax"
);
"movq %%cr0, %%rax\n"
"btsq $1, %%rax\n" /* cr0.mp */
"btrq $2, %%rax\n" /* cr0.em */
"movq %%rax, %%cr0\n"
"movq %%cr4, %%rax\n"
"bts $9, %%rax\n" /* cr4.osfxsr */
"movq %%rax, %%cr4\n"
::: "%rax"
);
}
 
/** Set the TS flag to 1.
/** Set the TS flag to 1.
*
* If a thread accesses coprocessor, exception is run, which
* does a lazy fpu context switch.
99,26 → 97,22
*/
void fpu_disable(void)
{
asm volatile (
"mov %%cr0,%%rax;"
"bts $3,%%rax;"
"mov %%rax,%%cr0;"
:
:
:"%rax"
);
asm volatile (
"mov %%cr0, %%rax\n"
"bts $3, %%rax\n"
"mov %%rax, %%cr0\n"
::: "%rax"
);
}
 
void fpu_enable(void)
{
asm volatile (
"mov %%cr0,%%rax;"
"btr $3,%%rax;"
"mov %%rax,%%cr0;"
:
:
:"%rax"
);
asm volatile (
"mov %%cr0, %%rax\n"
"btr $3, %%rax\n"
"mov %%rax, %%cr0\n"
::: "%rax"
);
}
 
void cpu_arch_init(void)
/branches/arm/kernel/arch/amd64/src/userspace.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64
/** @addtogroup amd64
* @{
*/
/** @file
47,36 → 47,33
*/
void userspace(uspace_arg_t *kernel_uarg)
{
ipl_t ipl;
ipl_t ipl = interrupts_disable();
ipl = interrupts_disable();
 
/* Clear CF,PF,AF,ZF,SF,DF,OF */
/* Clear CF, PF, AF, ZF, SF, DF, OF */
ipl &= ~(0xcd4);
 
asm volatile (""
"pushq %0\n"
"pushq %1\n"
"pushq %2\n"
"pushq %3\n"
"pushq %4\n"
"movq %5, %%rax\n"
/* %rdi is defined to hold pcb_ptr - set it to 0 */
"xorq %%rdi, %%rdi\n"
"iretq\n"
: :
"i" (gdtselector(UDATA_DES) | PL_USER),
"r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE),
"r" (ipl),
"i" (gdtselector(UTEXT_DES) | PL_USER),
"r" (kernel_uarg->uspace_entry),
"r" (kernel_uarg->uspace_uarg)
: "rax"
);
asm volatile (
"pushq %[udata_des]\n"
"pushq %[stack_size]\n"
"pushq %[ipl]\n"
"pushq %[utext_des]\n"
"pushq %[entry]\n"
"movq %[uarg], %%rax\n"
/* %rdi is defined to hold pcb_ptr - set it to 0 */
"xorq %%rdi, %%rdi\n"
"iretq\n"
:: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER),
[stack_size] "r" (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)
: "rax"
);
/* Unreachable */
for(;;)
;
while (1);
}
 
/** @}
/branches/arm/kernel/arch/amd64/src/mm/page.c
180,7 → 180,7
page = read_cr2();
if (istate->error_word & PFERR_CODE_RSVD)
panic("Reserved bit set in page table entry.\n");
panic("Reserved bit set in page table entry.");
if (istate->error_word & PFERR_CODE_RW)
access = PF_ACCESS_WRITE;
190,11 → 190,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(n, istate);
printf("Page fault address: %llx\n", page);
panic("page fault\n");
printf("Page fault address: %llx.\n", page);
panic("Page fault.");
}
}
 
202,7 → 202,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;
/branches/arm/kernel/arch/amd64/src/proc/scheduler.c
39,7 → 39,6
#include <arch.h>
#include <arch/context.h> /* SP_DELTA */
#include <arch/asm.h>
#include <arch/debugger.h>
#include <print.h>
#include <arch/pm.h>
#include <arch/ddi/ddi.h>
68,13 → 67,6
 
/* TLS support - set FS to thread local storage */
write_msr(AMD_MSR_FS, 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)
breakpoint_add(&((the_t *) THREAD->kstack)->as,
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, CPU->id);
#endif
}
 
void after_thread_ran_arch(void)
/branches/arm/kernel/arch/amd64/src/asm_utils.S
26,23 → 26,17
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
 
#define IREGISTER_SPACE 120
#define IREGISTER_SPACE 72
 
#define IOFFSET_RAX 0x0
#define IOFFSET_RBX 0x8
#define IOFFSET_RCX 0x10
#define IOFFSET_RDX 0x18
#define IOFFSET_RSI 0x20
#define IOFFSET_RDI 0x28
#define IOFFSET_R8 0x30
#define IOFFSET_R9 0x38
#define IOFFSET_R10 0x40
#define IOFFSET_R11 0x48
#define IOFFSET_R12 0x50
#define IOFFSET_R13 0x58
#define IOFFSET_R14 0x60
#define IOFFSET_R15 0x68
#define IOFFSET_RBP 0x70
#define IOFFSET_RAX 0x0
#define IOFFSET_RCX 0x8
#define IOFFSET_RDX 0x10
#define IOFFSET_RSI 0x18
#define IOFFSET_RDI 0x20
#define IOFFSET_R8 0x28
#define IOFFSET_R9 0x30
#define IOFFSET_R10 0x38
#define IOFFSET_R11 0x40
 
# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
# and 1 means interrupt with error word
173,7 → 167,7
rdmsr
ret
 
# Push all general purpose registers on stack except %rbp, %rsp
# Push all volatile general purpose registers on stack
.macro save_all_gpr
movq %rax, IOFFSET_RAX(%rsp)
movq %rcx, IOFFSET_RCX(%rsp)
184,14 → 178,6
movq %r9, IOFFSET_R9(%rsp)
movq %r10, IOFFSET_R10(%rsp)
movq %r11, IOFFSET_R11(%rsp)
#ifdef CONFIG_DEBUG_ALLREGS
movq %rbx, IOFFSET_RBX(%rsp)
movq %rbp, IOFFSET_RBP(%rsp)
movq %r12, IOFFSET_R12(%rsp)
movq %r13, IOFFSET_R13(%rsp)
movq %r14, IOFFSET_R14(%rsp)
movq %r15, IOFFSET_R15(%rsp)
#endif
.endm
 
.macro restore_all_gpr
204,21 → 190,9
movq IOFFSET_R9(%rsp), %r9
movq IOFFSET_R10(%rsp), %r10
movq IOFFSET_R11(%rsp), %r11
#ifdef CONFIG_DEBUG_ALLREGS
movq IOFFSET_RBX(%rsp), %rbx
movq IOFFSET_RBP(%rsp), %rbp
movq IOFFSET_R12(%rsp), %r12
movq IOFFSET_R13(%rsp), %r13
movq IOFFSET_R14(%rsp), %r14
movq IOFFSET_R15(%rsp), %r15
#endif
.endm
 
#ifdef CONFIG_DEBUG_ALLREGS
# define INTERRUPT_ALIGN 256
#else
# define INTERRUPT_ALIGN 128
#endif
#define INTERRUPT_ALIGN 128
## Declare interrupt handlers
#
/branches/arm/kernel/arch/amd64/_link.ld.in
43,8 → 43,6
QUAD(unmapped_kdata_end - unmapped_kdata_start);
*(COMMON); /* global variables */
 
*(.eh_frame);
 
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol!*/
 
52,6 → 50,10
 
kdata_end = .;
}
 
/DISCARD/ : {
*(*);
}
#ifdef CONFIG_SMP
_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
/branches/arm/kernel/arch/ia32/include/byteorder.h
File deleted
/branches/arm/kernel/arch/ia32/include/types.h
46,8 → 46,6
typedef unsigned long long uint64_t;
 
typedef uint32_t size_t;
typedef uint32_t count_t;
typedef uint32_t index_t;
 
typedef uint32_t uintptr_t;
typedef uint32_t pfn_t;
57,10 → 55,11
typedef uint32_t unative_t;
typedef int32_t native_t;
 
typedef struct {
} fncptr_t;
 
#define PRIp "x" /**< Format for uintptr_t. */
#define PRIs "u" /**< Format for size_t. */
#define PRIc "u" /**< Format for count_t. */
#define PRIi "u" /**< Format for index_t. */
 
#define PRId8 "d" /**< Format for int8_t. */
#define PRId16 "d" /**< Format for int16_t. */
/branches/arm/kernel/arch/ia32/include/smp/smp.h
39,10 → 39,10
 
/** SMP config opertaions interface. */
struct smp_config_operations {
count_t (* cpu_count)(void); /**< Return number of detected processors. */
bool (* cpu_enabled)(index_t i); /**< Check whether the processor of index i is enabled. */
bool (*cpu_bootstrap)(index_t i); /**< Check whether the processor of index i is BSP. */
uint8_t (*cpu_apic_id)(index_t i); /**< Return APIC ID of the processor of index i. */
size_t (* cpu_count)(void); /**< Return number of detected processors. */
bool (* cpu_enabled)(size_t i); /**< Check whether the processor of index i is enabled. */
bool (*cpu_bootstrap)(size_t i); /**< Check whether the processor of index i is BSP. */
uint8_t (*cpu_apic_id)(size_t i); /**< Return APIC ID of the processor of index i. */
int (*irq_to_pin)(unsigned int irq); /**< Return mapping between irq and APIC pin. */
};
 
/branches/arm/kernel/arch/ia32/include/proc/task.h
40,7 → 40,7
 
typedef struct {
/** I/O Permission bitmap Generation counter. */
count_t iomapver;
size_t iomapver;
/** I/O Permission bitmap. */
bitmap_t iomap;
} task_arch_t;
/branches/arm/kernel/arch/ia32/include/mm/page.h
95,21 → 95,21
 
/* Get PTE flags accessors for each level. */
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
get_pt_flags((pte_t *) (ptl0), (index_t) (i))
get_pt_flags((pte_t *) (ptl0), (size_t) (i))
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
PAGE_PRESENT
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
PAGE_PRESENT
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
get_pt_flags((pte_t *) (ptl3), (index_t) (i))
get_pt_flags((pte_t *) (ptl3), (size_t) (i))
 
/* Set PTE flags accessors for each level. */
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl0), (size_t) (i), (x))
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x))
set_pt_flags((pte_t *) (ptl3), (size_t) (i), (x))
 
/* Macros for querying the last level entries. */
#define PTE_VALID_ARCH(p) \
145,7 → 145,7
/** When bit on this position is 1, a reserved bit was set in page directory. */
#define PFERR_CODE_RSVD (1 << 3)
 
static inline int get_pt_flags(pte_t *pt, index_t i)
static inline int get_pt_flags(pte_t *pt, size_t i)
{
pte_t *p = &pt[i];
158,7 → 158,7
p->global << PAGE_GLOBAL_SHIFT);
}
 
static inline void set_pt_flags(pte_t *pt, index_t i, int flags)
static inline void set_pt_flags(pte_t *pt, size_t i, int flags)
{
pte_t *p = &pt[i];
/branches/arm/kernel/arch/ia32/include/mm/frame.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32mm
/** @addtogroup ia32mm
* @{
*/
/** @file
35,8 → 35,8
#ifndef KERN_ia32_FRAME_H_
#define KERN_ia32_FRAME_H_
 
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
#define FRAME_WIDTH 12 /* 4K */
#define FRAME_SIZE (1 << FRAME_WIDTH)
 
#ifdef KERNEL
#ifndef __ASM__
/branches/arm/kernel/arch/ia32/include/mm/tlb.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32mm
/** @addtogroup ia32mm
* @{
*/
/** @file
35,9 → 35,6
#ifndef KERN_ia32_TLB_H_
#define KERN_ia32_TLB_H_
 
#define tlb_arch_init()
#define tlb_print()
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia32/include/mm/as.h
42,7 → 42,7
#define USER_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x00000000)
#define USER_ADDRESS_SPACE_END_ARCH ((unsigned long) 0x7fffffff)
 
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1))
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1))
 
typedef struct {
} as_arch_t;
/branches/arm/kernel/arch/ia32/include/cpu.h
35,25 → 35,33
#ifndef KERN_ia32_CPU_H_
#define KERN_ia32_CPU_H_
 
#define EFLAGS_IF (1 << 9)
#define EFLAGS_RF (1 << 16)
 
#define CR4_OSFXSR_MASK (1<<9)
 
/* Support for SYSENTER and SYSEXIT */
#define IA32_MSR_SYSENTER_CS 0x174
#define IA32_MSR_SYSENTER_ESP 0x175
#define IA32_MSR_SYSENTER_EIP 0x176
 
#ifndef __ASM__
 
#include <arch/pm.h>
#include <arch/asm.h>
 
#define EFLAGS_IF (1 << 9)
#define EFLAGS_RF (1 << 16)
 
typedef struct {
int vendor;
int family;
int model;
int stepping;
struct tss *tss;
unsigned int vendor;
unsigned int family;
unsigned int model;
unsigned int stepping;
tss_t *tss;
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
size_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
} cpu_arch_t;
 
#endif
 
#define CR4_OSFXSR_MASK (1<<9)
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia32/include/atomic.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
41,17 → 41,29
 
static inline void atomic_inc(atomic_t *val) {
#ifdef CONFIG_SMP
asm volatile ("lock incl %0\n" : "+m" (val->count));
asm volatile (
"lock incl %[count]\n"
: [count] "+m" (val->count)
);
#else
asm volatile ("incl %0\n" : "+m" (val->count));
asm volatile (
"incl %[count]\n"
: [count] "+m" (val->count)
);
#endif /* CONFIG_SMP */
}
 
static inline void atomic_dec(atomic_t *val) {
#ifdef CONFIG_SMP
asm volatile ("lock decl %0\n" : "+m" (val->count));
asm volatile (
"lock decl %[count]\n"
: [count] "+m" (val->count)
);
#else
asm volatile ("decl %0\n" : "+m" (val->count));
asm volatile (
"decl %[count]\n"
: [count] "+m" (val->count)
);
#endif /* CONFIG_SMP */
}
 
58,12 → 70,12
static inline long atomic_postinc(atomic_t *val)
{
long r = 1;
 
asm volatile (
"lock xaddl %1, %0\n"
: "+m" (val->count), "+r" (r)
"lock xaddl %[r], %[count]\n"
: [count] "+m" (val->count), [r] "+r" (r)
);
 
return r;
}
 
72,23 → 84,23
long r = -1;
asm volatile (
"lock xaddl %1, %0\n"
: "+m" (val->count), "+r"(r)
"lock xaddl %[r], %[count]\n"
: [count] "+m" (val->count), [r] "+r"(r)
);
return r;
}
 
#define atomic_preinc(val) (atomic_postinc(val) + 1)
#define atomic_predec(val) (atomic_postdec(val) - 1)
#define atomic_preinc(val) (atomic_postinc(val) + 1)
#define atomic_predec(val) (atomic_postdec(val) - 1)
 
static inline uint32_t test_and_set(atomic_t *val) {
uint32_t v;
asm volatile (
"movl $1, %0\n"
"xchgl %0, %1\n"
: "=r" (v),"+m" (val->count)
"movl $1, %[v]\n"
"xchgl %[v], %[count]\n"
: [v] "=r" (v), [count] "+m" (val->count)
);
return v;
98,22 → 110,20
static inline void atomic_lock_arch(atomic_t *val)
{
uint32_t tmp;
 
preemption_disable();
asm volatile (
"0:\n"
#ifdef CONFIG_HT
"pause\n" /* Pentium 4's HT love this instruction */
#endif
"mov %0, %1\n"
"testl %1, %1\n"
"pause\n" /* Pentium 4's HT love this instruction */
"mov %[count], %[tmp]\n"
"testl %[tmp], %[tmp]\n"
"jnz 0b\n" /* lightweight looping on locked spinlock */
"incl %1\n" /* now use the atomic operation */
"xchgl %0, %1\n"
"testl %1, %1\n"
"incl %[tmp]\n" /* now use the atomic operation */
"xchgl %[count], %[tmp]\n"
"testl %[tmp], %[tmp]\n"
"jnz 0b\n"
: "+m" (val->count), "=&r"(tmp)
: [count] "+m" (val->count), [tmp] "=&r" (tmp)
);
/*
* Prevent critical section code from bleeding out this way up.
/branches/arm/kernel/arch/ia32/include/cpuid.h
35,6 → 35,13
#ifndef KERN_ia32_CPUID_H_
#define KERN_ia32_CPUID_H_
 
#define INTEL_CPUID_LEVEL 0x00000000
#define INTEL_CPUID_STANDARD 0x00000001
#define INTEL_PSE 3
#define INTEL_SEP 11
 
#ifndef __ASM__
 
#include <arch/types.h>
 
typedef struct {
74,21 → 81,21
uint32_t val, ret;
asm volatile (
"pushf\n" /* read flags */
"popl %0\n"
"movl %0, %1\n"
"pushf\n" /* read flags */
"popl %[ret]\n"
"movl %[ret], %[val]\n"
"btcl $21, %1\n" /* swap the ID bit */
"btcl $21, %[val]\n" /* swap the ID bit */
"pushl %1\n" /* propagate the change into flags */
"pushl %[val]\n" /* propagate the change into flags */
"popf\n"
"pushf\n"
"popl %1\n"
"popl %[val]\n"
"andl $(1 << 21), %0\n" /* interrested only in ID bit */
"andl $(1 << 21), %1\n"
"xorl %1, %0\n"
: "=r" (ret), "=r" (val)
"andl $(1 << 21), %[ret]\n" /* interrested only in ID bit */
"andl $(1 << 21), %[val]\n"
"xorl %[val], %[ret]\n"
: [ret] "=r" (ret), [val] "=r" (val)
);
return ret;
98,11 → 105,13
{
asm volatile (
"cpuid\n"
: "=a" (info->cpuid_eax), "=b" (info->cpuid_ebx), "=c" (info->cpuid_ecx), "=d" (info->cpuid_edx)
: "=a" (info->cpuid_eax), "=b" (info->cpuid_ebx),
"=c" (info->cpuid_ecx), "=d" (info->cpuid_edx)
: "a" (cmd)
);
}
 
#endif /* !def __ASM__ */
#endif
 
/** @}
/branches/arm/kernel/arch/ia32/include/pm.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
35,61 → 35,59
#ifndef KERN_ia32_PM_H_
#define KERN_ia32_PM_H_
 
#define IDT_ITEMS 64
#define GDT_ITEMS 7
#define IDT_ITEMS 64
#define GDT_ITEMS 7
 
#define VESA_INIT_SEGMENT 0x8000
#define NULL_DES 0
#define KTEXT_DES 1
#define KDATA_DES 2
#define UTEXT_DES 3
#define UDATA_DES 4
#define TSS_DES 5
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */
 
#define NULL_DES 0
#define KTEXT_DES 1
#define KDATA_DES 2
#define UTEXT_DES 3
#define UDATA_DES 4
#define TSS_DES 5
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */
 
#ifdef CONFIG_FB
 
#define VESA_INIT_SEGMENT 0x8000
#define VESA_INIT_DES 7
#define VESA_INIT_SEGMENT 0x8000
#define VESA_INIT_DES 7
#define KTEXT32_DES KTEXT_DES
 
#undef GDT_ITEMS
#define GDT_ITEMS 8
#define GDT_ITEMS 8
 
#endif /* CONFIG_FB */
 
#define gdtselector(des) ((des) << 3)
 
#define selector(des) ((des) << 3)
#define PL_KERNEL 0
#define PL_USER 3
 
#define PL_KERNEL 0
#define PL_USER 3
#define AR_PRESENT (1 << 7)
#define AR_DATA (2 << 3)
#define AR_CODE (3 << 3)
#define AR_WRITABLE (1 << 1)
#define AR_INTERRUPT (0x0e)
#define AR_TSS (0x09)
 
#define AR_PRESENT (1 << 7)
#define AR_DATA (2 << 3)
#define AR_CODE (3 << 3)
#define AR_WRITABLE (1 << 1)
#define AR_INTERRUPT (0xe)
#define AR_TSS (0x9)
#define DPL_KERNEL (PL_KERNEL << 5)
#define DPL_USER (PL_USER << 5)
 
#define DPL_KERNEL (PL_KERNEL << 5)
#define DPL_USER (PL_USER << 5)
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */
 
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */
#define IO_PORTS (64 * 1024)
 
#define IO_PORTS (64 * 1024)
 
#ifndef __ASM__
 
#include <arch/types.h>
#include <arch/context.h>
 
struct ptr_16_32 {
typedef struct {
uint16_t limit;
uint32_t base;
} __attribute__ ((packed));
typedef struct ptr_16_32 ptr_16_32_t;
} __attribute__ ((packed)) ptr_16_32_t;
 
struct descriptor {
typedef struct {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
100,19 → 98,17
unsigned special: 1;
unsigned granularity : 1;
unsigned base_24_31: 8;
} __attribute__ ((packed));
typedef struct descriptor descriptor_t;
} __attribute__ ((packed)) descriptor_t;
 
struct idescriptor {
typedef struct {
unsigned offset_0_15: 16;
unsigned selector: 16;
unsigned unused: 8;
unsigned access: 8;
unsigned offset_16_31: 16;
} __attribute__ ((packed));
typedef struct idescriptor idescriptor_t;
} __attribute__ ((packed)) idescriptor_t;
 
struct tss {
typedef struct {
uint16_t link;
unsigned : 16;
uint32_t esp0;
152,13 → 148,12
unsigned : 16;
uint16_t iomap_base;
uint8_t iomap[TSS_IOMAP_SIZE];
} __attribute__ ((packed));
typedef struct tss tss_t;
} __attribute__ ((packed)) tss_t;
 
extern ptr_16_32_t gdtr;
extern ptr_16_32_t bootstrap_gdtr;
extern ptr_16_32_t protected_ap_gdtr;
extern struct tss *tss_p;
extern tss_t *tss_p;
 
extern descriptor_t gdt[];
 
/branches/arm/kernel/arch/ia32/include/drivers/i8042.h
File deleted
/branches/arm/kernel/arch/ia32/include/drivers/ega.h
File deleted
/branches/arm/kernel/arch/ia32/include/drivers/i8254.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
/branches/arm/kernel/arch/ia32/include/drivers/vesa.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
36,6 → 36,7
#define KERN_ia32_VESA_H_
 
extern int vesa_present(void);
extern void vesa_redraw(void);
extern void vesa_init(void);
 
#endif
/branches/arm/kernel/arch/ia32/include/drivers/i8259.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
38,13 → 38,13
#include <arch/types.h>
#include <arch/interrupt.h>
 
#define PIC_PIC0PORT1 0x20
#define PIC_PIC0PORT2 0x21
#define PIC_PIC1PORT1 0xa0
#define PIC_PIC1PORT2 0xa1
#define PIC_PIC0PORT1 ((ioport8_t *) 0x20)
#define PIC_PIC0PORT2 ((ioport8_t *) 0x21)
#define PIC_PIC1PORT1 ((ioport8_t *) 0xa0)
#define PIC_PIC1PORT2 ((ioport8_t *) 0xa1)
 
#define PIC_NEEDICW4 (1<<0)
#define PIC_ICW1 (1<<4)
#define PIC_NEEDICW4 (1 << 0)
#define PIC_ICW1 (1 << 4)
 
extern void i8259_init(void);
extern void pic_enable_irqs(uint16_t irqmask);
/branches/arm/kernel/arch/ia32/include/asm.h
27,7 → 27,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
38,6 → 38,7
 
#include <arch/pm.h>
#include <arch/types.h>
#include <typedefs.h>
#include <config.h>
 
extern uint32_t interrupt_handler_size;
55,11 → 56,16
 
/** Halt CPU
*
* Halt the current CPU until interrupt event.
* Halt the current CPU.
*
*/
static inline void cpu_halt(void)
{
asm volatile ("hlt\n");
asm volatile (
"0:\n"
" hlt\n"
" jmp 0b\n"
);
}
 
static inline void cpu_sleep(void)
68,16 → 74,22
}
 
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \
{ \
unative_t res; \
asm volatile ("movl %%" #reg ", %0" : "=r" (res) ); \
return res; \
}
{ \
unative_t res; \
asm volatile ( \
"movl %%" #reg ", %[res]" \
: [res] "=r" (res) \
); \
return res; \
}
 
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \
{ \
asm volatile ("movl %0, %%" #reg : : "r" (regn)); \
}
{ \
asm volatile ( \
"movl %[regn], %%" #reg \
:: [regn] "r" (regn) \
); \
}
 
GEN_READ_REG(cr0)
GEN_READ_REG(cr2)
104,10 → 116,14
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void outb(uint16_t port, uint8_t val)
static inline void pio_write_8(ioport8_t *port, uint8_t val)
{
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) );
asm volatile (
"outb %b[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Word to port
116,10 → 132,14
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void outw(uint16_t port, uint16_t val)
static inline void pio_write_16(ioport16_t *port, uint16_t val)
{
asm volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) );
asm volatile (
"outw %w[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Double word to port
128,10 → 148,14
*
* @param port Port to write to
* @param val Value to write
*
*/
static inline void outl(uint16_t port, uint32_t val)
static inline void pio_write_32(ioport32_t *port, uint32_t val)
{
asm volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) );
asm volatile (
"outl %[val], %w[port]\n"
:: [val] "a" (val), [port] "d" (port)
);
}
 
/** Byte from port
140,12 → 164,18
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint8_t inb(uint16_t port)
static inline uint8_t pio_read_8(ioport8_t *port)
{
uint8_t val;
asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) );
asm volatile (
"inb %w[port], %b[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
155,12 → 185,18
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint16_t inw(uint16_t port)
static inline uint16_t pio_read_16(ioport16_t *port)
{
uint16_t val;
asm volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) );
asm volatile (
"inw %w[port], %w[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
170,12 → 206,18
*
* @param port Port to read from
* @return Value read
*
*/
static inline uint32_t inl(uint16_t port)
static inline uint32_t pio_read_32(ioport32_t *port)
{
uint32_t val;
asm volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) );
asm volatile (
"inl %w[port], %[val]\n"
: [val] "=a" (val)
: [port] "d" (port)
);
return val;
}
 
185,16 → 227,19
* value of EFLAGS.
*
* @return Old interrupt priority level.
*
*/
static inline ipl_t interrupts_enable(void)
{
ipl_t v;
asm volatile (
"pushf\n\t"
"popl %0\n\t"
"pushf\n"
"popl %[v]\n"
"sti\n"
: "=r" (v)
: [v] "=r" (v)
);
return v;
}
 
204,16 → 249,19
* value of EFLAGS.
*
* @return Old interrupt priority level.
*
*/
static inline ipl_t interrupts_disable(void)
{
ipl_t v;
asm volatile (
"pushf\n\t"
"popl %0\n\t"
"pushf\n"
"popl %[v]\n"
"cli\n"
: "=r" (v)
: [v] "=r" (v)
);
return v;
}
 
222,13 → 270,14
* Restore EFLAGS.
*
* @param ipl Saved interrupt priority level.
*
*/
static inline void interrupts_restore(ipl_t ipl)
{
asm volatile (
"pushl %0\n\t"
"pushl %[ipl]\n"
"popf\n"
: : "r" (ipl)
:: [ipl] "r" (ipl)
);
}
 
235,23 → 284,51
/** Return interrupt priority level.
*
* @return EFLAFS.
*
*/
static inline ipl_t interrupts_read(void)
{
ipl_t v;
asm volatile (
"pushf\n\t"
"popl %0\n"
: "=r" (v)
"pushf\n"
"popl %[v]\n"
: [v] "=r" (v)
);
return v;
}
 
/** Write to MSR */
static inline void write_msr(uint32_t msr, uint64_t value)
{
asm volatile (
"wrmsr"
:: "c" (msr), "a" ((uint32_t) (value)),
"d" ((uint32_t) (value >> 32))
);
}
 
static inline uint64_t read_msr(uint32_t msr)
{
uint32_t ax, dx;
asm volatile (
"rdmsr"
: "=a" (ax), "=d" (dx)
: "c" (msr)
);
return ((uint64_t) dx << 32) | ax;
}
 
 
/** Return base address of current stack
*
* Return the base address of the current stack.
* The stack is assumed to be STACK_SIZE bytes long.
* The stack must start on page boundary.
*
*/
static inline uintptr_t get_stack_base(void)
{
258,8 → 335,8
uintptr_t v;
asm volatile (
"andl %%esp, %0\n"
: "=r" (v)
"andl %%esp, %[v]\n"
: [v] "=r" (v)
: "0" (~(STACK_SIZE - 1))
);
270,11 → 347,12
static inline uintptr_t * get_ip()
{
uintptr_t *ip;
 
asm volatile (
"mov %%eip, %0"
: "=r" (ip)
);
"mov %%eip, %[ip]"
: [ip] "=r" (ip)
);
return ip;
}
 
281,46 → 359,66
/** Invalidate TLB Entry.
*
* @param addr Address on a page whose TLB entry is to be invalidated.
*
*/
static inline void invlpg(uintptr_t addr)
{
asm volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr));
asm volatile (
"invlpg %[addr]\n"
:: [addr] "m" (*(unative_t *) addr)
);
}
 
/** Load GDTR register from memory.
*
* @param gdtr_reg Address of memory from where to load GDTR.
*
*/
static inline void gdtr_load(ptr_16_32_t *gdtr_reg)
{
asm volatile ("lgdtl %0\n" : : "m" (*gdtr_reg));
asm volatile (
"lgdtl %[gdtr_reg]\n"
:: [gdtr_reg] "m" (*gdtr_reg)
);
}
 
/** Store GDTR register to memory.
*
* @param gdtr_reg Address of memory to where to load GDTR.
*
*/
static inline void gdtr_store(ptr_16_32_t *gdtr_reg)
{
asm volatile ("sgdtl %0\n" : : "m" (*gdtr_reg));
asm volatile (
"sgdtl %[gdtr_reg]\n"
:: [gdtr_reg] "m" (*gdtr_reg)
);
}
 
/** Load IDTR register from memory.
*
* @param idtr_reg Address of memory from where to load IDTR.
*
*/
static inline void idtr_load(ptr_16_32_t *idtr_reg)
{
asm volatile ("lidtl %0\n" : : "m" (*idtr_reg));
asm volatile (
"lidtl %[idtr_reg]\n"
:: [idtr_reg] "m" (*idtr_reg)
);
}
 
/** Load TR from descriptor table.
*
* @param sel Selector specifying descriptor of TSS segment.
*
*/
static inline void tr_load(uint16_t sel)
{
asm volatile ("ltr %0" : : "r" (sel));
asm volatile (
"ltr %[sel]"
:: [sel] "r" (sel)
);
}
 
#endif
/branches/arm/kernel/arch/ia32/include/boot/boot.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
35,15 → 35,24
#ifndef KERN_ia32_BOOT_H_
#define KERN_ia32_BOOT_H_
 
#define BOOT_OFFSET 0x108000
#define AP_BOOT_OFFSET 0x8000
#define BOOT_STACK_SIZE 0x400
#define BOOT_OFFSET 0x108000
#define AP_BOOT_OFFSET 0x8000
#define BOOT_STACK_SIZE 0x400
 
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
#define MULTIBOOT_HEADER_FLAGS 0x00010003
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002
#define MULTIBOOT_HEADER_FLAGS 0x00010003
 
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002
#ifndef __ASM__
 
#ifdef CONFIG_SMP
 
/* This is only a symbol so the type is dummy. Obtain the value using &. */
extern int _hardcoded_unmapped_size;
 
#endif /* CONFIG_SMP */
 
#endif /* __ASM__ */
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia32/include/boot/memmap.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
35,24 → 35,29
#ifndef KERN_ia32_MEMMAP_H_
#define KERN_ia32_MEMMAP_H_
 
/* E820h memory range types - other values*/
/* Free memory */
#define MEMMAP_MEMORY_AVAILABLE 1
/* Not available for OS */
#define MEMMAP_MEMORY_RESERVED 2
/* OS may use it after reading ACPI table */
#define MEMMAP_MEMORY_ACPI 3
/* Unusable, required to be saved and restored across an NVS sleep */
#define MEMMAP_MEMORY_NVS 4
/* Corrupted memory */
#define MEMMAP_MEMORY_UNUSABLE 5
/* E820h memory range types */
 
/* size of one entry */
#define MEMMAP_E820_RECORD_SIZE 20
/* maximum entries */
#define MEMMAP_E820_MAX_RECORDS 32
/* Free memory */
#define MEMMAP_MEMORY_AVAILABLE 1
 
/* Not available for OS */
#define MEMMAP_MEMORY_RESERVED 2
 
/* OS may use it after reading ACPI table */
#define MEMMAP_MEMORY_ACPI 3
 
/* Unusable, required to be saved and restored across an NVS sleep */
#define MEMMAP_MEMORY_NVS 4
 
/* Corrupted memory */
#define MEMMAP_MEMORY_UNUSABLE 5
 
/* Size of one entry */
#define MEMMAP_E820_RECORD_SIZE 20
 
/* Maximum entries */
#define MEMMAP_E820_MAX_RECORDS 32
 
#ifndef __ASM__
 
#include <arch/types.h>
/branches/arm/kernel/arch/ia32/include/arch.h
1,5 → 1,5
/*
* Copyright (c) 2005 Martin Decky
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
35,6 → 35,10
#ifndef KERN_ia32_ARCH_H_
#define KERN_ia32_ARCH_H_
 
#include <genarch/multiboot/multiboot.h>
 
extern void arch_pre_main(uint32_t, const multiboot_info_t *);
 
#endif
 
/** @}
/branches/arm/kernel/arch/ia32/include/barrier.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
46,8 → 46,8
* Provisions are made to prevent compiler from reordering instructions itself.
*/
 
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory")
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory")
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory")
 
static inline void cpuid_serialization(void)
{
58,30 → 58,30
);
}
 
#ifdef CONFIG_FENCES_P4
# define memory_barrier() asm volatile ("mfence\n" ::: "memory")
# define read_barrier() asm volatile ("lfence\n" ::: "memory")
# ifdef CONFIG_WEAK_MEMORY
# define write_barrier() asm volatile ("sfence\n" ::: "memory")
# else
# define write_barrier() asm volatile( "" ::: "memory");
# endif
#elif CONFIG_FENCES_P3
# define memory_barrier() cpuid_serialization()
# define read_barrier() cpuid_serialization()
# ifdef CONFIG_WEAK_MEMORY
# define write_barrier() asm volatile ("sfence\n" ::: "memory")
# else
# define write_barrier() asm volatile( "" ::: "memory");
# endif
#if defined(CONFIG_FENCES_P4)
#define memory_barrier() asm volatile ("mfence\n" ::: "memory")
#define read_barrier() asm volatile ("lfence\n" ::: "memory")
#ifdef CONFIG_WEAK_MEMORY
#define write_barrier() asm volatile ("sfence\n" ::: "memory")
#else
#define write_barrier() asm volatile ("" ::: "memory");
#endif
#elif defined(CONFIG_FENCES_P3)
#define memory_barrier() cpuid_serialization()
#define read_barrier() cpuid_serialization()
#ifdef CONFIG_WEAK_MEMORY
#define write_barrier() asm volatile ("sfence\n" ::: "memory")
#else
#define write_barrier() asm volatile ("" ::: "memory");
#endif
#else
# define memory_barrier() cpuid_serialization()
# define read_barrier() cpuid_serialization()
# ifdef CONFIG_WEAK_MEMORY
# define write_barrier() cpuid_serialization()
# else
# define write_barrier() asm volatile( "" ::: "memory");
# endif
#define memory_barrier() cpuid_serialization()
#define read_barrier() cpuid_serialization()
#ifdef CONFIG_WEAK_MEMORY
#define write_barrier() cpuid_serialization()
#else
#define write_barrier() asm volatile ("" ::: "memory");
#endif
#endif
 
/*
90,8 → 90,8
* queueing in the store buffer drain to the memory (even though it would be
* sufficient for them to drain to the D-cache).
*/
#define smc_coherence(a) write_barrier()
#define smc_coherence_block(a, l) write_barrier()
#define smc_coherence(a) write_barrier()
#define smc_coherence_block(a, l) write_barrier()
 
#endif
 
/branches/arm/kernel/arch/ia32/include/interrupt.h
72,10 → 72,6
uint32_t eax;
uint32_t ecx;
uint32_t edx;
uint32_t esi;
uint32_t edi;
uint32_t ebp;
uint32_t ebx;
 
uint32_t gs;
uint32_t fs;
/branches/arm/kernel/arch/ia32/include/fpu_context.h
37,7 → 37,6
 
#include <arch/types.h>
 
#define ARCH_HAS_FPU
#define FPU_CONTEXT_ALIGN 16
 
void fpu_fxsr(void);
/branches/arm/kernel/arch/ia32/include/syscall.h
0,0 → 1,0
link ../../amd64/include/syscall.h
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/arm/kernel/arch/ia32/Makefile.inc
29,10 → 29,6
## Toolchain configuration
#
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
BFD_NAME = elf32-i386
BFD_ARCH = i386
BFD = binary
39,7 → 35,8
TARGET = i686-pc-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686
 
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__
BITS = 32
ENDIANESS = LE
 
CMN1 = -m32
GCC_CFLAGS += $(CMN1)
49,115 → 46,61
## Accepted CPUs
#
 
ifeq ($(MACHINE),athlon-xp)
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-3dnow
ifeq ($(PROCESSOR),athlon_xp)
CMN2 = -march=athlon-xp
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xarch=ssea
DEFS += -DCONFIG_FENCES_P3
CONFIG_SMP = n
CONFIG_HT = n
endif
ifeq ($(MACHINE),athlon-mp)
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-3dnow
ifeq ($(PROCESSOR),athlon_mp)
CMN2 = -march=athlon-mp
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += xarch=ssea
DEFS += -DCONFIG_FENCES_P3
CONFIG_HT = n
endif
ifeq ($(MACHINE),pentium3)
FPU_NO_CFLAGS = -mno-mmx -mno-sse
ifeq ($(PROCESSOR),pentium3)
CMN2 = -march=pentium3
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xarch=sse
DEFS += -DCONFIG_FENCES_P3
CONFIG_HT = n
endif
ifeq ($(MACHINE),core)
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2 -mno-sse3
ifeq ($(PROCESSOR),pentium4)
CMN2 = -march=pentium4
SUNCC_CFLAGS += -xarch=sse2
endif
ifeq ($(PROCESSOR),core)
CMN2 = -march=prescott
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
SUNCC_CFLAGS += -xarch=sse3
DEFS += -DCONFIG_FENCES_P4
endif
ifeq ($(MACHINE),pentium4)
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2
GCC_CFLAGS += -march=pentium4
ICC_CFLAGS += -march=pentium4
SUNCC_CFLAGS += -xarch=sse2
DEFS += -DCONFIG_FENCES_P4
endif
 
## Own configuration directives
#
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
 
CONFIG_ACPI = y
 
## Compile with hierarchical page tables support.
#
 
CONFIG_PAGE_PT = y
DEFS += -DCONFIG_PAGE_PT
 
## Compile with i8042 controller support
#
 
CONFIG_I8042 = y
DEFS += -DCONFIG_I8042
 
## Accepted configuration directives
#
 
ifeq ($(CONFIG_SMP),y)
DEFS += -DCONFIG_SMP
endif
ifeq ($(CONFIG_HT),y)
DEFS += -DCONFIG_HT
endif
ifeq ($(CONFIG_SIMICS_FIX),y)
DEFS += -DCONFIG_SIMICS_FIX
endif
 
## Compile with support for software integer division.
#
 
CONFIG_SOFTINT = y
 
ARCH_SOURCES = \
arch/$(ARCH)/src/context.S \
arch/$(ARCH)/src/debug/panic.s \
arch/$(ARCH)/src/delay.s \
arch/$(ARCH)/src/asm.S \
arch/$(ARCH)/src/proc/scheduler.c \
arch/$(ARCH)/src/proc/task.c \
arch/$(ARCH)/src/proc/thread.c \
arch/$(ARCH)/src/bios/bios.c \
arch/$(ARCH)/src/smp/ap.S \
arch/$(ARCH)/src/smp/apic.c \
arch/$(ARCH)/src/smp/mps.c \
arch/$(ARCH)/src/smp/smp.c \
arch/$(ARCH)/src/atomic.S \
arch/$(ARCH)/src/smp/ipi.c \
arch/$(ARCH)/src/ia32.c \
arch/$(ARCH)/src/interrupt.c \
arch/$(ARCH)/src/pm.c \
arch/$(ARCH)/src/userspace.c \
arch/$(ARCH)/src/cpu/cpu.c \
arch/$(ARCH)/src/mm/as.c \
arch/$(ARCH)/src/mm/frame.c \
arch/$(ARCH)/src/mm/page.c \
arch/$(ARCH)/src/mm/tlb.c \
arch/$(ARCH)/src/ddi/ddi.c \
arch/$(ARCH)/src/drivers/i8254.c \
arch/$(ARCH)/src/drivers/i8259.c \
arch/$(ARCH)/src/drivers/ega.c \
arch/$(ARCH)/src/drivers/vesa.c \
arch/$(ARCH)/src/boot/boot.S \
arch/$(ARCH)/src/boot/memmap.c \
arch/$(ARCH)/src/fpu_context.c \
arch/$(ARCH)/src/debugger.c
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/debug/panic.s \
arch/$(KARCH)/src/delay.s \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/proc/scheduler.c \
arch/$(KARCH)/src/proc/task.c \
arch/$(KARCH)/src/proc/thread.c \
arch/$(KARCH)/src/bios/bios.c \
arch/$(KARCH)/src/smp/ap.S \
arch/$(KARCH)/src/smp/apic.c \
arch/$(KARCH)/src/smp/mps.c \
arch/$(KARCH)/src/smp/smp.c \
arch/$(KARCH)/src/atomic.S \
arch/$(KARCH)/src/smp/ipi.c \
arch/$(KARCH)/src/ia32.c \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/pm.c \
arch/$(KARCH)/src/userspace.c \
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/mm/frame.c \
arch/$(KARCH)/src/mm/page.c \
arch/$(KARCH)/src/mm/tlb.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/drivers/i8254.c \
arch/$(KARCH)/src/drivers/i8259.c \
arch/$(KARCH)/src/drivers/vesa.c \
arch/$(KARCH)/src/boot/boot.S \
arch/$(KARCH)/src/boot/memmap.c \
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/debugger.c \
arch/$(KARCH)/src/syscall.c
/branches/arm/kernel/arch/ia32/src/smp/mps.c
86,10 → 86,10
/*
* Implementation of IA-32 SMP configuration interface.
*/
static count_t get_cpu_count(void);
static bool is_cpu_enabled(index_t i);
static bool is_bsp(index_t i);
static uint8_t get_cpu_apic_id(index_t i);
static size_t get_cpu_count(void);
static bool is_cpu_enabled(size_t i);
static bool is_bsp(size_t i);
static uint8_t get_cpu_apic_id(size_t i);
static int mps_irq_to_pin(unsigned int irq);
 
struct smp_config_operations mps_config_operations = {
100,24 → 100,24
.irq_to_pin = mps_irq_to_pin
};
 
count_t get_cpu_count(void)
size_t get_cpu_count(void)
{
return processor_entry_cnt;
}
 
bool is_cpu_enabled(index_t i)
bool is_cpu_enabled(size_t i)
{
ASSERT(i < processor_entry_cnt);
return (bool) ((processor_entries[i].cpu_flags & 0x01) == 0x01);
}
 
bool is_bsp(index_t i)
bool is_bsp(size_t i)
{
ASSERT(i < processor_entry_cnt);
return (bool) ((processor_entries[i].cpu_flags & 0x02) == 0x02);
}
 
uint8_t get_cpu_apic_id(index_t i)
uint8_t get_cpu_apic_id(size_t i)
{
ASSERT(i < processor_entry_cnt);
return processor_entries[i].l_apic_id;
/branches/arm/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/arm/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/arm/kernel/arch/ia32/src/ddi/ddi.c
57,7 → 57,7
*/
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
count_t bits;
size_t bits;
 
bits = ioaddr + size;
if (bits > IO_PORTS)
99,7 → 99,7
/*
* Enable the range and we are done.
*/
bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size);
 
/*
* Increment I/O Permission bitmap generation counter.
118,10 → 118,10
*/
void io_perm_bitmap_install(void)
{
count_t bits;
size_t bits;
ptr_16_32_t cpugdtr;
descriptor_t *gdt_p;
count_t ver;
size_t ver;
 
/* First, copy the I/O Permission Bitmap. */
spinlock_lock(&TASK->lock);
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/arm/kernel/arch/ia32/src/mm/tlb.c
59,7 → 59,7
* @param page Address of the first page whose entry is to be invalidated.
* @param cnt Number of entries to invalidate.
*/
void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, count_t cnt)
void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, size_t cnt)
{
unsigned int i;
 
67,5 → 67,13
invlpg(page + i * PAGE_SIZE);
}
 
void tlb_arch_init(void)
{
}
 
void tlb_print(void)
{
}
 
/** @}
*/
/branches/arm/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;
size_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/arm/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/arm/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. */
105,7 → 101,7
static void gp_fault(int n __attribute__((unused)), istate_t *istate)
{
if (TASK) {
count_t ver;
size_t ver;
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
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/arm/kernel/arch/ia32/src/atomic.S
42,9 → 42,7
movl 12(%esp),%ebx
 
0:
#ifdef CONFIG_HT
pause # Pentium 4's with HT love this instruction
#endif
movl (%ebx),%eax
testl %eax,%eax
jnz 0b # lightweight looping while it is locked
/branches/arm/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,33
 
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.
*/
i8042_instance_t *i8042_instance = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD);
if (i8042_instance) {
kbrd_instance_t *kbrd_instance = kbrd_init();
if (kbrd_instance) {
indev_t *sink = stdin_wire();
indev_t *kbrd = kbrd_wire(kbrd_instance, sink);
i8042_wire(i8042_instance, kbrd);
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 → 209,45
*/
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;
}
 
void arch_reboot(void)
{
#ifdef CONFIG_PC_KBD
i8042_cpu_reset((i8042_t *) I8042_BASE);
#endif
}
 
/** @}
*/
/branches/arm/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 */
232,28 → 232,5
gdtr_load(&cpugdtr);
}
 
/* Reboot the machine by initiating
* a triple fault
*/
void arch_reboot(void)
{
preemption_disable();
ipl_t ipl = interrupts_disable();
memsetb(idt, sizeof(idt), 0);
ptr_16_32_t idtr;
idtr.limit = sizeof(idt);
idtr.base = (uintptr_t) idt;
idtr_load(&idtr);
interrupts_restore(ipl);
asm volatile (
"int $0x03\n"
"cli\n"
"hlt\n"
);
}
 
/** @}
*/
/branches/arm/kernel/arch/ia32/src/boot/boot.S
31,6 → 31,7
#include <arch/boot/memmap.h>
#include <arch/mm/page.h>
#include <arch/pm.h>
#include <arch/cpuid.h>
 
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
 
42,40 → 43,41
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?
movl $(INTEL_CPUID_LEVEL), %eax
cpuid
cmp $0x0, %eax # any function > 0?
jbe pse_unsupported
movl $0x1, %eax # Basic function code 1
movl $(INTEL_CPUID_STANDARD), %eax
cpuid
bt $3, %edx # Test if PSE is supported
bt $(INTEL_PSE), %edx
jc pse_supported
 
pse_unsupported:
movl $pse_msg, %esi
jmp error_halt
82,138 → 84,31
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
bt $(INTEL_SEP), %edx
jc sep_supported
vesa_meeting_point:
movl $sep_msg, %esi
jmp error_halt
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
sep_supported:
 
#include "vesa_prot.inc"
 
# map kernel and turn paging on
call map_kernel
call map_kernel # map kernel and turn paging on
# call arch_pre_main(grub_eax, grub_ebx)
pushl grub_ebx
pushl grub_eax
call arch_pre_main
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:
call main_bsp
#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 → 117,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 → 125,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 → 157,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 → 166,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 → 175,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 → 182,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 → 194,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 → 201,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
551,3 → 223,6
 
pse_msg:
.asciz "Page Size Extension not supported. System halted."
 
sep_msg:
.asciz "SYSENTER/SYSEXIT not supported. System halted."
/branches/arm/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/arm/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/arm/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/arm/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/arm/kernel/arch/ia32/src/drivers/ega.c
File deleted
/branches/arm/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/arm/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)) +
/branches/arm/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/arm/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/arm/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/arm/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/arm/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/arm/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/arm/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/arm/kernel/arch/ia32/_link.ld.in
1,11 → 1,11
/** IA-32 linker script
*
*
* umapped section:
* kernel text
* kernel data
* kernel text
* kernel data
* mapped section:
* kernel text
* kernel data
* kernel text
* kernel data
*/
 
#include <arch/boot/boot.h>
28,9 → 28,9
ktext_end = .;
kdata_start = .;
*(.data); /* initialized data */
*(.rodata*); /* string literals */
*(COMMON); /* global variables */
*(.data); /* initialized data */
*(.rodata*); /* string literals */
*(COMMON); /* global variables */
hardcoded_load_address = .;
LONG(PA2KA(BOOT_OFFSET));
hardcoded_ktext_size = .;
42,23 → 42,23
hardcoded_unmapped_kdata_size = .;
LONG(unmapped_kdata_end - unmapped_kdata_start);
symbol_table = .;
*(symtab.*); /* Symbol table, must be LAST symbol! */
*(.bss); /* uninitialized static variables */
*(symtab.*); /* Symbol table, must be LAST symbol! */
*(.bss); /* uninitialized static variables */
kdata_end = .;
}
 
/DISCARD/ : {
*(.note.GNU-stack);
*(.note.GNU-stack);
*(.comment);
}
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start);
ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET;
ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET;
protected_ap_gdtr = PA2KA(ap_gdtr);
 
#endif /* CONFIG_SMP */
 
}
/branches/arm/kernel/generic/include/context.h
45,7 → 45,7
(c)->sp = ((uintptr_t) (stack)) + (size) - SP_DELTA;
#endif /* context_set */
 
extern int context_save_arch(context_t *c);
extern int context_save_arch(context_t *c) __attribute__ ((returns_twice));
extern void context_restore_arch(context_t *c) __attribute__ ((noreturn));
 
/** Save register context.
76,10 → 76,6
* corresponding call to context_save(), the only
* difference being return value.
*
* Note that content of any local variable defined by
* the caller of context_save() is undefined after
* context_restore().
*
* @param c Context structure.
*/
static inline void context_restore(context_t *c)
/branches/arm/kernel/generic/include/byteorder.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
35,32 → 35,48
#ifndef KERN_BYTEORDER_H_
#define KERN_BYTEORDER_H_
 
#include <arch/byteorder.h>
#include <arch/types.h>
 
#if !(defined(ARCH_IS_BIG_ENDIAN) ^ defined(ARCH_IS_LITTLE_ENDIAN))
#error The architecture must be either big-endian or little-endian.
#if !(defined(__BE__) ^ defined(__LE__))
#error The architecture must be either big-endian or little-endian.
#endif
 
#ifdef ARCH_IS_BIG_ENDIAN
#ifdef __BE__
 
#define uint16_t_le2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_le2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_le2host(n) uint64_t_byteorder_swap(n)
#define uint16_t_le2host(n) (uint16_t_byteorder_swap(n))
#define uint32_t_le2host(n) (uint32_t_byteorder_swap(n))
#define uint64_t_le2host(n) (uint64_t_byteorder_swap(n))
 
#define uint16_t_be2host(n) (n)
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
#define uint16_t_be2host(n) (n)
#define uint32_t_be2host(n) (n)
#define uint64_t_be2host(n) (n)
 
#define host2uint16_t_le(n) (uint16_t_byteorder_swap(n))
#define host2uint32_t_le(n) (uint32_t_byteorder_swap(n))
#define host2uint64_t_le(n) (uint64_t_byteorder_swap(n))
 
#define host2uint16_t_be(n) (n)
#define host2uint32_t_be(n) (n)
#define host2uint64_t_be(n) (n)
 
#else
 
#define uint16_t_le2host(n) (n)
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
#define uint16_t_le2host(n) (n)
#define uint32_t_le2host(n) (n)
#define uint64_t_le2host(n) (n)
 
#define uint16_t_be2host(n) uint16_t_byteorder_swap(n)
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n)
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n)
#define uint16_t_be2host(n) (uint16_t_byteorder_swap(n))
#define uint32_t_be2host(n) (uint32_t_byteorder_swap(n))
#define uint64_t_be2host(n) (uint64_t_byteorder_swap(n))
 
#define host2uint16_t_le(n) (n)
#define host2uint32_t_le(n) (n)
#define host2uint64_t_le(n) (n)
 
#define host2uint16_t_be(n) (uint16_t_byteorder_swap(n))
#define host2uint32_t_be(n) (uint32_t_byteorder_swap(n))
#define host2uint64_t_be(n) (uint64_t_byteorder_swap(n))
 
#endif
 
static inline uint64_t uint64_t_byteorder_swap(uint64_t n)
/branches/arm/kernel/generic/include/string.h
0,0 → 1,99
/*
* Copyright (c) 2001-2004 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 generic
* @{
*/
/** @file
*/
 
#ifndef KERN_STRING_H_
#define KERN_STRING_H_
 
#include <typedefs.h>
 
/**< Common Unicode characters */
#define U_SPECIAL '?'
 
#define U_LEFT_ARROW 0x2190
#define U_UP_ARROW 0x2191
#define U_RIGHT_ARROW 0x2192
#define U_DOWN_ARROW 0x2193
 
#define U_PAGE_UP 0x21de
#define U_PAGE_DOWN 0x21df
 
#define U_HOME_ARROW 0x21f1
#define U_END_ARROW 0x21f2
 
#define U_NULL 0x2400
#define U_ESCAPE 0x241b
#define U_DELETE 0x2421
 
#define U_CURSOR 0x2588
 
/**< No size limit constant */
#define STR_NO_LIMIT ((size_t) -1)
 
/**< Maximum size of a string containing cnt characters */
#define STR_BOUNDS(cnt) (cnt << 2)
 
extern wchar_t str_decode(const char *str, size_t *offset, size_t sz);
extern int chr_encode(wchar_t ch, char *str, size_t *offset, size_t sz);
 
extern size_t str_size(const char *str);
extern size_t wstr_size(const wchar_t *str);
 
extern size_t str_lsize(const char *str, size_t max_len);
extern size_t wstr_lsize(const wchar_t *str, size_t max_len);
 
extern size_t str_length(const char *str);
extern size_t wstr_length(const wchar_t *wstr);
 
extern size_t str_nlength(const char *str, size_t size);
extern size_t wstr_nlength(const wchar_t *str, size_t size);
 
extern bool ascii_check(wchar_t ch);
extern bool chr_check(wchar_t ch);
 
extern int str_cmp(const char *s1, const char *s2);
extern int str_lcmp(const char *s1, const char *s2, size_t max_len);
 
extern void str_cpy(char *dest, size_t size, const char *src);
extern void str_ncpy(char *dest, size_t size, const char *src, size_t n);
extern void wstr_nstr(char *dst, const wchar_t *src, size_t size);
 
extern const char *str_chr(const char *str, wchar_t ch);
 
extern bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos);
extern bool wstr_remove(wchar_t *str, size_t pos);
 
#endif
 
/** @}
*/
/branches/arm/kernel/generic/include/symtab.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
44,15 → 44,20
char symbol_name[MAX_SYMBOL_NAME];
};
 
extern char * get_symtab_entry(unative_t addr);
extern uintptr_t get_symbol_addr(const char *name);
extern int symtab_name_lookup(unative_t addr, char **name);
extern char *symtab_fmt_name_lookup(unative_t addr);
extern int symtab_addr_lookup(const char *name, uintptr_t *addr);
extern void symtab_print_search(const char *name);
extern int symtab_compl(char *name);
extern int symtab_compl(char *input, size_t size);
 
#ifdef CONFIG_SYMTAB
 
/* Symtable linked together by build process */
extern struct symtab_entry symbol_table[];
 
#endif
 
#endif
 
/** @}
*/
/branches/arm/kernel/generic/include/config.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
38,17 → 38,19
#include <arch/types.h>
#include <arch/mm/page.h>
 
#define STACK_SIZE PAGE_SIZE
#define STACK_SIZE PAGE_SIZE
 
#define CONFIG_INIT_TASKS 32
#define CONFIG_INIT_TASKS 32
#define CONFIG_TASK_NAME_BUFLEN 32
 
typedef struct {
uintptr_t addr;
size_t size;
char name[CONFIG_TASK_NAME_BUFLEN];
} init_task_t;
 
typedef struct {
count_t cnt;
size_t cnt;
init_task_t tasks[CONFIG_INIT_TASKS];
} init_t;
 
63,14 → 65,14
} ballocs_t;
 
typedef struct {
count_t cpu_count; /**< Number of processors detected. */
volatile count_t cpu_active; /**< Number of processors that are up and running. */
 
size_t cpu_count; /**< Number of processors detected. */
volatile size_t cpu_active; /**< Number of processors that are up and running. */
uintptr_t base;
size_t kernel_size; /**< Size of memory in bytes taken by kernel and stack */
size_t kernel_size; /**< Size of memory in bytes taken by kernel and stack */
uintptr_t stack_base; /**< Base adddress of initial stack */
size_t stack_size; /**< Size of initial stack */
uintptr_t stack_base; /**< Base adddress of initial stack */
size_t stack_size; /**< Size of initial stack */
} config_t;
 
extern config_t config;
/branches/arm/kernel/generic/include/proc/scheduler.h
47,7 → 47,7
typedef struct {
SPINLOCK_DECLARE(lock);
link_t rq_head; /**< List of ready threads. */
count_t n; /**< Number of threads in rq_ready. */
size_t n; /**< Number of threads in rq_ready. */
} runq_t;
 
extern atomic_t nrdy;
/branches/arm/kernel/generic/include/proc/task.h
53,7 → 53,10
#include <mm/tlb.h>
#include <proc/scheduler.h>
#include <udebug/udebug.h>
#include <ipc/kbox.h>
 
#define TASK_NAME_BUFLEN 20
 
struct thread;
 
/** Task structure. */
67,8 → 70,8
* threads.
*/
SPINLOCK_DECLARE(lock);
char *name;
 
char name[TASK_NAME_BUFLEN];
/** List of threads contained in this task. */
link_t th_head;
/** Address space. */
96,19 → 99,13
atomic_t active_calls;
 
#ifdef CONFIG_UDEBUG
/** Debugging stuff */
/** Debugging stuff. */
udebug_task_t udebug;
 
/** Kernel answerbox */
answerbox_t kernel_box;
/** Thread used to service kernel answerbox */
struct thread *kb_thread;
/** Kbox thread creation vs. begin of cleanup mutual exclusion */
mutex_t kb_cleanup_lock;
/** True if cleanup of kbox has already started */
bool kb_finished;
/** Kernel answerbox. */
kbox_t kb;
#endif
 
/** Architecture specific task data. */
task_arch_t arch;
147,6 → 144,7
#endif
 
extern unative_t sys_task_get_id(task_id_t *uspace_task_id);
extern unative_t sys_task_set_name(const char *uspace_name, size_t name_len);
 
#endif
 
/branches/arm/kernel/generic/include/proc/program.h
52,12 → 52,14
 
extern void *program_loader;
 
extern void program_create(as_t *as, uintptr_t entry_addr, program_t *p);
extern int program_create_from_image(void *image_addr, program_t *p);
extern int program_create_loader(program_t *p);
extern void program_create(as_t *as, uintptr_t entry_addr, char *name,
program_t *p);
extern int program_create_from_image(void *image_addr, char *name,
program_t *p);
extern int program_create_loader(program_t *p, char *name);
extern void program_ready(program_t *p);
 
extern unative_t sys_program_spawn_loader(int *uspace_phone_id);
extern unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len);
 
#endif
 
/branches/arm/kernel/generic/include/proc/thread.h
259,7 → 259,8
extern slab_cache_t *fpu_context_slab;
 
/* Thread syscall prototypes. */
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name, thread_id_t *uspace_thread_id);
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg,
char *uspace_name, size_t name_len, thread_id_t *uspace_thread_id);
extern unative_t sys_thread_exit(int uspace_status);
extern unative_t sys_thread_get_id(thread_id_t *uspace_thread_id);
 
/branches/arm/kernel/generic/include/cpu.h
51,18 → 51,18
SPINLOCK_DECLARE(lock);
 
tlb_shootdown_msg_t tlb_messages[TLB_MESSAGE_QUEUE_LEN];
count_t tlb_messages_count;
size_t tlb_messages_count;
context_t saved_context;
 
atomic_t nrdy;
runq_t rq[RQ_COUNT];
volatile count_t needs_relink;
volatile size_t needs_relink;
 
SPINLOCK_DECLARE(timeoutlock);
link_t timeout_active_head;
 
count_t missed_clock_ticks; /**< When system clock loses a tick, it is recorded here
size_t missed_clock_ticks; /**< When system clock loses a tick, it is recorded here
so that clock() can react. This variable is
CPU-local and can be only accessed when interrupts
are disabled. */
/branches/arm/kernel/generic/include/synch/futex.h
49,7 → 49,7
/** Futex hash table link. */
link_t ht_link;
/** Number of tasks that reference this futex. */
count_t refcount;
size_t refcount;
} futex_t;
 
extern void futex_init(void);
/branches/arm/kernel/generic/include/synch/rwlock.h
53,7 → 53,7
*/
mutex_t exclusive;
/** Number of readers in critical section. */
count_t readers_in;
size_t readers_in;
} rwlock_t;
 
#define rwlock_write_lock(rwl) \
/branches/arm/kernel/generic/include/synch/spinlock.h
36,6 → 36,7
#define KERN_SPINLOCK_H_
 
#include <arch/types.h>
#include <arch/barrier.h>
#include <preemption.h>
#include <atomic.h>
#include <debug.h>
106,7 → 107,7
extern int printf(const char *, ...);
 
#define DEADLOCK_THRESHOLD 100000000
#define DEADLOCK_PROBE_INIT(pname) count_t pname = 0
#define DEADLOCK_PROBE_INIT(pname) size_t pname = 0
#define DEADLOCK_PROBE(pname, value) \
if ((pname)++ > (value)) { \
(pname) = 0; \
/branches/arm/kernel/generic/include/ddi/irq.h
36,18 → 36,16
#define KERN_IRQ_H_
 
typedef enum {
CMD_MEM_READ_1 = 0,
CMD_MEM_READ_2,
CMD_MEM_READ_4,
CMD_MEM_READ_8,
CMD_MEM_WRITE_1,
CMD_MEM_WRITE_2,
CMD_MEM_WRITE_4,
CMD_MEM_WRITE_8,
CMD_PORT_READ_1,
CMD_PORT_WRITE_1,
CMD_IA64_GETCHAR,
CMD_PPC32_GETCHAR,
CMD_PIO_READ_8 = 1,
CMD_PIO_READ_16,
CMD_PIO_READ_32,
CMD_PIO_WRITE_8,
CMD_PIO_WRITE_16,
CMD_PIO_WRITE_32,
CMD_BTEST,
CMD_PREDICATE,
CMD_ACCEPT,
CMD_DECLINE,
CMD_LAST
} irq_cmd_type;
 
54,8 → 52,9
typedef struct {
irq_cmd_type cmd;
void *addr;
unsigned long long value;
int dstarg;
unsigned long long value;
unsigned int srcarg;
unsigned int dstarg;
} irq_cmd_t;
 
typedef struct {
67,8 → 66,10
 
#include <arch/types.h>
#include <adt/list.h>
#include <adt/hash_table.h>
#include <synch/spinlock.h>
#include <proc/task.h>
#include <ipc/ipc.h>
 
typedef enum {
IRQ_DECLINE, /**< Decline to service. */
81,8 → 82,11
} irq_trigger_t;
 
struct irq;
typedef void (* irq_handler_t)(struct irq *irq, void *arg, ...);
typedef void (* irq_handler_t)(struct irq *);
 
/** Type for function used to clear the interrupt. */
typedef void (* cir_t)(void *, inr_t);
 
/** IPC notification config structure.
*
* Primarily, this structure is encapsulated in the irq_t structure.
95,10 → 99,12
answerbox_t *answerbox;
/** Method to be used for the notification. */
unative_t method;
/** Arguments that will be sent if the IRQ is claimed. */
unative_t scratch[IPC_CALL_LEN];
/** Top-half pseudocode. */
irq_code_t *code;
/** Counter. */
count_t counter;
size_t counter;
/**
* Link between IRQs that are notifying the same answerbox. The list is
* protected by the answerbox irq_lock.
138,22 → 144,29
/** Trigger level of the IRQ. */
irq_trigger_t trigger;
/** Claim ownership of the IRQ. */
irq_ownership_t (* claim)(void);
irq_ownership_t (* claim)(struct irq *);
/** Handler for this IRQ and device. */
irq_handler_t handler;
/** Argument for the handler. */
void *arg;
/** Instance argument for the handler and the claim function. */
void *instance;
 
/** Clear interrupt routine. */
cir_t cir;
/** First argument to the clear interrupt routine. */
void *cir_arg;
 
/** Notification configuration structure. */
ipc_notif_cfg_t notif_cfg;
} irq_t;
 
extern void irq_init(count_t inrs, count_t chains);
extern void irq_initialize(irq_t *irq);
extern void irq_register(irq_t *irq);
extern irq_t *irq_dispatch_and_lock(inr_t inr);
extern irq_t *irq_find_and_lock(inr_t inr, devno_t devno);
SPINLOCK_EXTERN(irq_uspace_hash_table_lock);
extern hash_table_t irq_uspace_hash_table;
 
extern void irq_init(size_t, size_t);
extern void irq_initialize(irq_t *);
extern void irq_register(irq_t *);
extern irq_t *irq_dispatch_and_lock(inr_t);
 
#endif
 
#endif
/branches/arm/kernel/generic/include/ddi/device.h
39,6 → 39,7
#include <typedefs.h>
 
extern devno_t device_assign_devno(void);
extern unative_t sys_device_assign_devno(void);
 
#endif
 
/branches/arm/kernel/generic/include/ddi/ddi.h
38,13 → 38,14
#include <ddi/ddi_arg.h>
#include <arch/types.h>
#include <proc/task.h>
#include <adt/list.h>
 
/** Structure representing contiguous physical memory area. */
typedef struct {
uintptr_t pbase; /**< Physical base of the area. */
uintptr_t vbase; /**< Virtual base of the area. */
count_t frames; /**< Number of frames in the area. */
bool cacheable; /**< Cacheability. */
uintptr_t pbase; /**< Physical base of the area. */
pfn_t frames; /**< Number of frames in the area. */
link_t link; /**< Linked list link */
} parea_t;
 
extern void ddi_init(void);
/branches/arm/kernel/generic/include/console/chardev.h
39,41 → 39,63
#include <synch/waitq.h>
#include <synch/spinlock.h>
 
#define CHARDEV_BUFLEN 512
#define INDEV_BUFLEN 512
 
struct chardev;
struct indev;
 
/* Character device operations interface. */
/* Input character device operations interface. */
typedef struct {
/** Suspend pushing characters. */
void (* suspend)(struct chardev *);
/** Resume pushing characters. */
void (* resume)(struct chardev *);
/** Write character to stream. */
void (* write)(struct chardev *, char c);
/** Read character directly from device, assume interrupts disabled. */
char (* read)(struct chardev *);
} chardev_operations_t;
wchar_t (* poll)(struct indev *);
} indev_operations_t;
 
/** Character input device. */
typedef struct chardev {
typedef struct indev {
char *name;
waitq_t wq;
waitq_t wq;
/** Protects everything below. */
SPINLOCK_DECLARE(lock);
uint8_t buffer[CHARDEV_BUFLEN];
count_t counter;
/** Implementation of chardev operations. */
chardev_operations_t *op;
index_t index;
SPINLOCK_DECLARE(lock);
wchar_t buffer[INDEV_BUFLEN];
size_t counter;
/** Implementation of indev operations. */
indev_operations_t *op;
size_t index;
void *data;
} chardev_t;
} indev_t;
 
extern void chardev_initialize(char *name, chardev_t *chardev,
chardev_operations_t *op);
extern void chardev_push_character(chardev_t *chardev, uint8_t ch);
 
struct outdev;
 
/* Output character device operations interface. */
typedef struct {
/** Write character to output. */
void (* write)(struct outdev *, wchar_t, bool);
} outdev_operations_t;
 
/** Character input device. */
typedef struct outdev {
char *name;
/** Protects everything below. */
SPINLOCK_DECLARE(lock);
/** Implementation of outdev operations. */
outdev_operations_t *op;
void *data;
} outdev_t;
 
extern void indev_initialize(char *name, indev_t *indev,
indev_operations_t *op);
extern void indev_push_character(indev_t *indev, wchar_t ch);
extern wchar_t indev_pop_character(indev_t *indev);
 
extern void outdev_initialize(char *name, outdev_t *outdev,
outdev_operations_t *op);
 
extern bool check_poll(indev_t *indev);
 
#endif /* KERN_CHARDEV_H_ */
 
/** @}
/branches/arm/kernel/generic/include/console/kconsole.h
37,9 → 37,10
 
#include <adt/list.h>
#include <synch/spinlock.h>
#include <ipc/irq.h>
 
#define MAX_CMDLINE 256
#define KCONSOLE_HISTORY 10
#define MAX_CMDLINE 256
#define KCONSOLE_HISTORY 10
 
typedef enum {
ARG_TYPE_INVALID = 0,
46,7 → 47,7
ARG_TYPE_INT,
ARG_TYPE_STRING,
/** Variable type - either symbol or string. */
ARG_TYPE_VAR
ARG_TYPE_VAR
} cmd_arg_type_t;
 
/** Structure representing one argument of kconsole command line. */
76,7 → 77,7
/** Function implementing the command. */
int (* func)(cmd_arg_t *);
/** Number of arguments. */
count_t argc;
size_t argc;
/** Argument vector. */
cmd_arg_t *argv;
/** Function for printing detailed help. */
83,13 → 84,19
void (* help)(void);
} cmd_info_t;
 
extern bool kconsole_notify;
extern irq_t kconsole_irq;
 
SPINLOCK_EXTERN(cmd_lock);
extern link_t cmd_head;
 
extern void kconsole_init(void);
extern void kconsole(void *prompt);
extern void kconsole_notify_init(void);
extern bool kconsole_check_poll(void);
extern void kconsole(char *prompt, char *msg, bool kcon);
extern void kconsole_thread(void *data);
 
extern int cmd_register(cmd_info_t *cmd);
extern bool cmd_register(cmd_info_t *cmd);
 
#endif
 
/branches/arm/kernel/generic/include/console/console.h
38,17 → 38,26
#include <arch/types.h>
#include <console/chardev.h>
 
extern chardev_t *stdin;
extern chardev_t *stdout;
extern indev_t *stdin;
extern outdev_t *stdout;
extern bool silent;
 
extern indev_t *stdin_wire(void);
extern void console_init(void);
 
extern void klog_init(void);
extern void klog_update(void);
 
extern uint8_t getc(chardev_t *chardev);
uint8_t _getc(chardev_t *chardev);
extern count_t gets(chardev_t *chardev, char *buf, size_t buflen);
extern void putchar(char c);
extern wchar_t getc(indev_t *indev);
extern size_t gets(indev_t *indev, char *buf, size_t buflen);
extern unative_t sys_klog(int fd, const void *buf, size_t size);
 
extern void grab_console(void);
extern void release_console(void);
 
extern unative_t sys_debug_enable_console(void);
extern unative_t sys_debug_disable_console(void);
 
extern void arch_grab_console(void);
extern void arch_release_console(void);
 
/branches/arm/kernel/generic/include/arch.h
56,7 → 56,7
* the base address of the stack.
*/
typedef struct {
count_t preemption_disabled; /**< Preemption disabled counter. */
size_t preemption_disabled; /**< Preemption disabled counter. */
thread_t *thread; /**< Current thread. */
task_t *task; /**< Current task. */
cpu_t *cpu; /**< Executing cpu. */
63,12 → 63,11
as_t *as; /**< Current address space. */
} the_t;
 
#define THE ((the_t *)(get_stack_base()))
#define THE ((the_t * )(get_stack_base()))
 
extern void the_initialize(the_t *the);
extern void the_copy(the_t *src, the_t *dst);
 
extern void arch_pre_main(void);
extern void arch_pre_mm_init(void);
extern void arch_post_mm_init(void);
extern void arch_post_cpu_init(void);
79,6 → 78,7
 
extern void reboot(void);
extern void arch_reboot(void);
extern void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller);
 
#endif
 
/branches/arm/kernel/generic/include/adt/hash_table.h
47,7 → 47,7
*
* @return Index into hash table.
*/
index_t (* hash)(unative_t key[]);
size_t (* hash)(unative_t key[]);
/** Hash table item comparison function.
*
56,7 → 56,7
*
* @return true if the keys match, false otherwise.
*/
bool (*compare)(unative_t key[], count_t keys, link_t *item);
bool (*compare)(unative_t key[], size_t keys, link_t *item);
 
/** Hash table item removal callback.
*
68,8 → 68,8
/** Hash table structure. */
typedef struct {
link_t *entry;
count_t entries;
count_t max_keys;
size_t entries;
size_t max_keys;
hash_table_operations_t *op;
} hash_table_t;
 
76,11 → 76,11
#define hash_table_get_instance(item, type, member) \
list_get_instance((item), type, member)
 
extern void hash_table_create(hash_table_t *h, count_t m, count_t max_keys,
extern void hash_table_create(hash_table_t *h, size_t m, size_t max_keys,
hash_table_operations_t *op);
extern void hash_table_insert(hash_table_t *h, unative_t key[], link_t *item);
extern link_t *hash_table_find(hash_table_t *h, unative_t key[]);
extern void hash_table_remove(hash_table_t *h, unative_t key[], count_t keys);
extern void hash_table_remove(hash_table_t *h, unative_t key[], size_t keys);
 
#endif
 
/branches/arm/kernel/generic/include/adt/bitmap.h
41,14 → 41,23
 
typedef struct {
uint8_t *map;
count_t bits;
size_t bits;
} bitmap_t;
 
extern void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, count_t bits);
extern void bitmap_set_range(bitmap_t *bitmap, index_t start, count_t bits);
extern void bitmap_clear_range(bitmap_t *bitmap, index_t start, count_t bits);
extern void bitmap_copy(bitmap_t *dst, bitmap_t *src, count_t bits);
extern void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, size_t bits);
extern void bitmap_set_range(bitmap_t *bitmap, size_t start, size_t bits);
extern void bitmap_clear_range(bitmap_t *bitmap, size_t start, size_t bits);
extern void bitmap_copy(bitmap_t *dst, bitmap_t *src, size_t bits);
 
static inline int bitmap_get(bitmap_t *bitmap, size_t bit)
{
if(bit >= bitmap->bits)
return 0;
return !! ((bitmap->map)[bit/8] & (1 << (bit & 7)));
}
 
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/adt/btree.h
46,7 → 46,7
/** B-tree node structure. */
typedef struct btree_node {
/** Number of keys. */
count_t keys;
size_t keys;
 
/**
* Keys. We currently support only single keys. Additional room for one
/branches/arm/kernel/generic/include/adt/fifo.h
59,9 → 59,9
#define FIFO_INITIALIZE_STATIC(name, t, itms) \
struct { \
t fifo[(itms)]; \
count_t items; \
index_t head; \
index_t tail; \
size_t items; \
size_t head; \
size_t tail; \
} name = { \
.items = (itms), \
.head = 0, \
80,9 → 80,9
#define FIFO_INITIALIZE_DYNAMIC(name, t, itms) \
struct { \
t *fifo; \
count_t items; \
index_t head; \
index_t tail; \
size_t items; \
size_t head; \
size_t tail; \
} name = { \
.fifo = NULL, \
.items = (itms), \
/branches/arm/kernel/generic/include/mm/frame.h
38,34 → 38,82
 
#include <arch/types.h>
#include <adt/list.h>
#include <mm/buddy.h>
#include <synch/spinlock.h>
#include <mm/buddy.h>
#include <arch/mm/page.h>
#include <arch/mm/frame.h>
 
#define ONE_FRAME 0
#define TWO_FRAMES 1
#define FOUR_FRAMES 2
#define ONE_FRAME 0
#define TWO_FRAMES 1
#define FOUR_FRAMES 2
 
 
#ifdef ARCH_STACK_FRAMES
#define STACK_FRAMES ARCH_STACK_FRAMES
#define STACK_FRAMES ARCH_STACK_FRAMES
#else
#define STACK_FRAMES ONE_FRAME
#define STACK_FRAMES ONE_FRAME
#endif
 
/** Maximum number of zones in system. */
#define ZONES_MAX 16
/** Maximum number of zones in the system. */
#define ZONES_MAX 32
 
/** Convert the frame address to kernel va. */
#define FRAME_KA 0x1
typedef uint8_t frame_flags_t;
 
/** Convert the frame address to kernel VA. */
#define FRAME_KA 0x01
/** Do not panic and do not sleep on failure. */
#define FRAME_ATOMIC 0x2
#define FRAME_ATOMIC 0x02
/** Do not start reclaiming when no free memory. */
#define FRAME_NO_RECLAIM 0x4
/** Do not allocate above 4 GiB. */
#define FRAME_LOW_4_GiB 0x8
#define FRAME_NO_RECLAIM 0x04
 
typedef uint8_t zone_flags_t;
 
/** Available zone (free for allocation) */
#define ZONE_AVAILABLE 0x00
/** Zone is reserved (not available for allocation) */
#define ZONE_RESERVED 0x08
/** Zone is used by firmware (not available for allocation) */
#define ZONE_FIRMWARE 0x10
 
/** Currently there is no equivalent zone flags
for frame flags */
#define FRAME_TO_ZONE_FLAGS(frame_flags) 0
 
typedef struct {
size_t refcount; /**< Tracking of shared frames */
uint8_t buddy_order; /**< Buddy system block order */
link_t buddy_link; /**< Link to the next free block inside
one order */
void *parent; /**< If allocated by slab, this points there */
} frame_t;
 
typedef struct {
pfn_t base; /**< Frame_no of the first frame
in the frames array */
size_t count; /**< Size of zone */
size_t free_count; /**< Number of free frame_t
structures */
size_t busy_count; /**< Number of busy frame_t
structures */
zone_flags_t flags; /**< Type of the zone */
frame_t *frames; /**< Array of frame_t structures
in this zone */
buddy_system_t *buddy_system; /**< Buddy system for the zone */
} zone_t;
 
/*
* The zoneinfo.lock must be locked when accessing zoneinfo structure.
* Some of the attributes in zone_t structures are 'read-only'
*/
typedef struct {
SPINLOCK_DECLARE(lock);
size_t count;
zone_t info[ZONES_MAX];
} zones_t;
 
extern zones_t zones;
 
static inline uintptr_t PFN2ADDR(pfn_t frame)
{
return (uintptr_t) (frame << FRAME_WIDTH);
76,43 → 124,49
return (pfn_t) (addr >> FRAME_WIDTH);
}
 
static inline count_t SIZE2FRAMES(size_t size)
static inline size_t SIZE2FRAMES(size_t size)
{
if (!size)
return 0;
return (count_t) ((size - 1) >> FRAME_WIDTH) + 1;
return (size_t) ((size - 1) >> FRAME_WIDTH) + 1;
}
 
static inline size_t FRAMES2SIZE(count_t frames)
static inline size_t FRAMES2SIZE(size_t frames)
{
return (size_t) (frames << FRAME_WIDTH);
}
 
#define IS_BUDDY_ORDER_OK(index, order) \
static inline bool zone_flags_available(zone_flags_t flags)
{
return ((flags & (ZONE_RESERVED | ZONE_FIRMWARE)) == 0);
}
 
#define IS_BUDDY_ORDER_OK(index, order) \
((~(((unative_t) -1) << (order)) & (index)) == 0)
#define IS_BUDDY_LEFT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
#define IS_BUDDY_RIGHT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0)
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1)
#define IS_BUDDY_LEFT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 0)
#define IS_BUDDY_RIGHT_BLOCK(zone, frame) \
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 1)
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 0)
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) \
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 1)
 
#define frame_alloc(order, flags) \
#define frame_alloc(order, flags) \
frame_alloc_generic(order, flags, NULL)
 
extern void frame_init(void);
extern void *frame_alloc_generic(uint8_t, int, unsigned int *);
extern void *frame_alloc_generic(uint8_t, frame_flags_t, size_t *);
extern void frame_free(uintptr_t);
extern void frame_reference_add(pfn_t);
 
extern int zone_create(pfn_t, count_t, pfn_t, int);
extern void *frame_get_parent(pfn_t, unsigned int);
extern void frame_set_parent(pfn_t, void *, unsigned int);
extern void frame_mark_unavailable(pfn_t, count_t);
extern uintptr_t zone_conf_size(count_t);
extern void zone_merge(unsigned int, unsigned int);
extern size_t find_zone(pfn_t frame, size_t count, size_t hint);
extern size_t zone_create(pfn_t, size_t, pfn_t, zone_flags_t);
extern void *frame_get_parent(pfn_t, size_t);
extern void frame_set_parent(pfn_t, void *, size_t);
extern void frame_mark_unavailable(pfn_t, size_t);
extern uintptr_t zone_conf_size(size_t);
extern bool zone_merge(size_t, size_t);
extern void zone_merge_all(void);
extern uint64_t zone_total_size(void);
 
120,7 → 174,7
* Console functions
*/
extern void zone_print_list(void);
extern void zone_print_one(unsigned int);
extern void zone_print_one(size_t);
 
#endif
 
/branches/arm/kernel/generic/include/mm/slab.h
41,40 → 41,40
#include <mm/frame.h>
 
/** Minimum size to be allocated by malloc */
#define SLAB_MIN_MALLOC_W 4
#define SLAB_MIN_MALLOC_W 4
 
/** Maximum size to be allocated by malloc */
#define SLAB_MAX_MALLOC_W 18
#define SLAB_MAX_MALLOC_W 22
 
/** Initial Magazine size (TODO: dynamically growing magazines) */
#define SLAB_MAG_SIZE 4
 
/** If object size is less, store control structure inside SLAB */
#define SLAB_INSIDE_SIZE (PAGE_SIZE >> 3)
#define SLAB_INSIDE_SIZE (PAGE_SIZE >> 3)
 
/** Maximum wasted space we allow for cache */
#define SLAB_MAX_BADNESS(cache) \
#define SLAB_MAX_BADNESS(cache) \
(((unsigned int) PAGE_SIZE << (cache)->order) >> 2)
 
/* slab_reclaim constants */
 
/** Reclaim all possible memory, because we are in memory stress */
#define SLAB_RECLAIM_ALL 0x1
#define SLAB_RECLAIM_ALL 0x01
 
/* cache_create flags */
 
/** Do not use per-cpu cache */
#define SLAB_CACHE_NOMAGAZINE 0x1
#define SLAB_CACHE_NOMAGAZINE 0x01
/** Have control structure inside SLAB */
#define SLAB_CACHE_SLINSIDE 0x2
#define SLAB_CACHE_SLINSIDE 0x02
/** We add magazine cache later, if we have this flag */
#define SLAB_CACHE_MAGDEFERRED (0x4 | SLAB_CACHE_NOMAGAZINE)
#define SLAB_CACHE_MAGDEFERRED (0x04 | SLAB_CACHE_NOMAGAZINE)
 
typedef struct {
link_t link;
count_t busy; /**< Count of full slots in magazine */
count_t size; /**< Number of slots in magazine */
void *objs[]; /**< Slots in magazine */
size_t busy; /**< Count of full slots in magazine */
size_t size; /**< Number of slots in magazine */
void *objs[]; /**< Slots in magazine */
} slab_magazine_t;
 
typedef struct {
86,23 → 86,23
 
typedef struct {
char *name;
 
link_t link;
 
/* Configuration */
/** Size of slab position - align_up(sizeof(obj)) */
size_t size;
 
int (*constructor)(void *obj, int kmflag);
int (*destructor)(void *obj);
 
/** Flags changing behaviour of cache */
int flags;
 
/* Computed values */
uint8_t order; /**< Order of frames to be allocated */
unsigned int objects; /**< Number of objects that fit in */
 
uint8_t order; /**< Order of frames to be allocated */
unsigned int objects; /**< Number of objects that fit in */
/* Statistics */
atomic_t allocated_slabs;
atomic_t allocated_objs;
109,15 → 109,15
atomic_t cached_objs;
/** How many magazines in magazines list */
atomic_t magazine_counter;
 
/* Slabs */
link_t full_slabs; /**< List of full slabs */
link_t partial_slabs; /**< List of partial slabs */
link_t full_slabs; /**< List of full slabs */
link_t partial_slabs; /**< List of partial slabs */
SPINLOCK_DECLARE(slablock);
/* Magazines */
link_t magazines; /**< List o full magazines */
/* Magazines */
link_t magazines; /**< List o full magazines */
SPINLOCK_DECLARE(maglock);
 
/** CPU cache */
slab_mag_cache_t *mag_cache;
} slab_cache_t;
128,7 → 128,7
 
extern void * slab_alloc(slab_cache_t *, int);
extern void slab_free(slab_cache_t *, void *);
extern count_t slab_reclaim(int);
extern size_t slab_reclaim(int);
 
/* slab subsytem initialization */
extern void slab_cache_init(void);
141,6 → 141,7
extern void *malloc(unsigned int, int);
extern void *realloc(void *, unsigned int, int);
extern void free(void *);
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/mm/tlb.h
61,7 → 61,7
tlb_invalidate_type_t type; /**< Message type. */
asid_t asid; /**< Address space identifier. */
uintptr_t page; /**< Page address. */
count_t count; /**< Number of pages to invalidate. */
size_t count; /**< Number of pages to invalidate. */
} tlb_shootdown_msg_t;
 
extern void tlb_init(void);
68,7 → 68,7
 
#ifdef CONFIG_SMP
extern void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
uintptr_t page, count_t count);
uintptr_t page, size_t count);
extern void tlb_shootdown_finalize(void);
extern void tlb_shootdown_ipi_recv(void);
#else
84,7 → 84,7
 
extern void tlb_invalidate_all(void);
extern void tlb_invalidate_asid(asid_t asid);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt);
#endif
 
/** @}
/branches/arm/kernel/generic/include/mm/as.h
94,7 → 94,7
* Number of processors on wich is this address space active.
* Protected by asidlock.
*/
count_t cpu_refcount;
size_t cpu_refcount;
/**
* Address space identifier.
* Constant on architectures that do not support ASIDs.
132,7 → 132,7
/** This lock must be acquired only when the as_area lock is held. */
mutex_t lock;
/** This structure can be deallocated if refcount drops to 0. */
count_t refcount;
size_t refcount;
/**
* B+tree containing complete map of anonymous pages of the shared area.
*/
156,7 → 156,7
};
struct { /**< phys_backend members */
uintptr_t base;
count_t frames;
size_t frames;
};
} mem_backend_data_t;
 
175,7 → 175,7
/** Attributes related to the address space area itself. */
int attributes;
/** Size of this area in multiples of PAGE_SIZE. */
count_t pages;
size_t pages;
/** Base address of this area. */
uintptr_t base;
/** Map of used space. */
225,8 → 225,8
extern int as_area_get_flags(as_area_t *area);
extern bool as_area_check_access(as_area_t *area, pf_access_t access);
extern size_t as_area_get_size(uintptr_t base);
extern int used_space_insert(as_area_t *a, uintptr_t page, count_t count);
extern int used_space_remove(as_area_t *a, uintptr_t page, count_t count);
extern int used_space_insert(as_area_t *a, uintptr_t page, size_t count);
extern int used_space_remove(as_area_t *a, uintptr_t page, size_t count);
 
 
/* Interface to be implemented by architectures. */
/branches/arm/kernel/generic/include/mm/page.h
42,7 → 42,7
/** Operations to manipulate page mappings. */
typedef struct {
void (* mapping_insert)(as_t *as, uintptr_t page, uintptr_t frame,
int flags);
int flags);
void (* mapping_remove)(as_t *as, uintptr_t page);
pte_t *(* mapping_find)(as_t *as, uintptr_t page);
} page_mapping_operations_t;
59,6 → 59,7
extern pte_t *page_table_create(int flags);
extern void page_table_destroy(pte_t *page_table);
extern void map_structure(uintptr_t s, size_t size);
 
extern uintptr_t hw_map(uintptr_t physaddr, size_t size);
 
#endif
/branches/arm/kernel/generic/include/mm/buddy.h
82,7 → 82,7
extern link_t *buddy_system_alloc(buddy_system_t *, uint8_t);
extern bool buddy_system_can_alloc(buddy_system_t *, uint8_t);
extern void buddy_system_free(buddy_system_t *, link_t *);
extern size_t buddy_conf_size(int);
extern size_t buddy_conf_size(size_t);
extern link_t *buddy_system_alloc_block(buddy_system_t *, link_t *);
 
#endif
/branches/arm/kernel/generic/include/ipc/event.h
0,0 → 1,79
/*
* Copyright (c) 2009 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 generic
* @{
*/
/** @file
*/
 
#ifndef KERN_EVENT_H_
#define KERN_EVENT_H_
 
#include <ipc/event_types.h>
#include <arch/types.h>
#include <synch/spinlock.h>
#include <ipc/ipc.h>
 
/** Event notification structure. */
typedef struct {
SPINLOCK_DECLARE(lock);
/** Answerbox for notifications. */
answerbox_t *answerbox;
/** Method to be used for the notification. */
unative_t method;
/** Counter. */
size_t counter;
} event_t;
 
extern void event_init(void);
extern unative_t sys_event_subscribe(unative_t, unative_t);
extern bool event_is_subscribed(event_type_t);
extern void event_cleanup_answerbox(answerbox_t *);
 
#define event_notify_0(e) \
event_notify((e), 0, 0, 0, 0, 0)
#define event_notify_1(e, a1) \
event_notify((e), (a1), 0, 0, 0, 0)
#define event_notify_2(e, a1, a2) \
event_notify((e), (a1), (a2), 0, 0, 0)
#define event_notify_3(e, a1, a2, a3) \
event_notify((e), (a1), (a2), (a3), 0, 0)
#define event_notify_4(e, a1, a2, a3, a4) \
event_notify((e), (a1), (a2), (a3), (a4), 0)
#define event_notify_5(e, a1, a2, a3, a4, a5) \
event_notify((e), (a1), (a2), (a3), (a4), (a5))
 
extern void event_notify(event_type_t, unative_t, unative_t, unative_t,
unative_t, unative_t);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/generic/include/ipc/event_types.h
0,0 → 1,53
/*
* Copyright (c) 2009 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 generic
* @{
*/
/** @file
*/
 
#ifndef KERN_EVENT_TYPES_H_
#define KERN_EVENT_TYPES_H_
 
typedef enum event_type {
EVENT_KLOG = 0,
EVENT_KCONSOLE,
EVENT_WAIT,
EVENT_END
} event_type_t;
 
typedef enum wait_type {
TASK_CREATE = 0,
TASK_DESTROY
} wait_type_t;
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/generic/include/ipc/ipc.h
111,6 → 111,25
/* System-specific methods - only through special syscalls
* These methods have special behaviour
*/
/** Clone connection.
*
* The calling task clones one of its phones for the callee.
*
* - ARG1 - The caller sets ARG1 to the phone of the cloned connection.
* - The callee gets the new phone from ARG1.
* - on answer, the callee acknowledges the new connection by sending EOK back
* or the kernel closes it
*/
#define IPC_M_CONNECTION_CLONE 1
/** Protocol for CONNECT - ME
*
* Through this call, the recipient learns about the new cloned connection.
*
* - ARG5 - the kernel sets ARG5 to contain the hash of the used phone
* - on asnwer, the callee acknowledges the new connection by sending EOK back
* or the kernel closes it
*/
#define IPC_M_CONNECT_ME 2
/** Protocol for CONNECT - TO - ME
*
* Calling process asks the callee to create a callback connection,
127,7 → 146,7
* - the allocated phoneid is passed to userspace
* (on the receiving side) as ARG5 of the call.
*/
#define IPC_M_CONNECT_TO_ME 1
#define IPC_M_CONNECT_TO_ME 3
/** Protocol for CONNECT - ME - TO
*
* Calling process asks the callee to create for him a new connection.
145,11 → 164,11
* - recepient may forward message.
*
*/
#define IPC_M_CONNECT_ME_TO 2
#define IPC_M_CONNECT_ME_TO 4
/** This message is sent to answerbox when the phone
* is hung up
*/
#define IPC_M_PHONE_HUNGUP 3
#define IPC_M_PHONE_HUNGUP 5
 
/** Send as_area over IPC.
* - ARG1 - source as_area base address
159,7 → 178,7
* on answer, the recipient must set:
* - ARG1 - dst as_area base adress
*/
#define IPC_M_SHARE_OUT 4
#define IPC_M_SHARE_OUT 6
 
/** Receive as_area over IPC.
* - ARG1 - destination as_area base address
171,7 → 190,7
* - ARG1 - source as_area base address
* - ARG2 - flags that will be used for sharing
*/
#define IPC_M_SHARE_IN 5
#define IPC_M_SHARE_IN 7
 
/** Send data to another address space over IPC.
* - ARG1 - source address space virtual address
182,7 → 201,7
* - ARG1 - final destination address space virtual address
* - ARG2 - final size of data to be copied
*/
#define IPC_M_DATA_WRITE 6
#define IPC_M_DATA_WRITE 8
 
/** Receive data from another address space over IPC.
* - ARG1 - destination virtual address in the source address space
193,13 → 212,13
* - ARG1 - source virtual address in the destination address space
* - ARG2 - final size of data to be copied
*/
#define IPC_M_DATA_READ 7
#define IPC_M_DATA_READ 9
 
/** Debug the recipient.
* - ARG1 - specifies the debug method (from udebug_method_t)
* - other arguments are specific to the debug method
*/
#define IPC_M_DEBUG_ALL 8
#define IPC_M_DEBUG_ALL 10
 
/* Well-known methods */
#define IPC_M_LAST_SYSTEM 511
/branches/arm/kernel/generic/include/ipc/ipcrsc.h
35,8 → 35,11
#ifndef KERN_IPCRSC_H_
#define KERN_IPCRSC_H_
 
#include <proc/task.h>
#include <ipc/ipc.h>
 
extern call_t * get_call(unative_t callid);
extern int phone_alloc(void);
extern int phone_alloc(task_t *t);
extern void phone_connect(int phoneid, answerbox_t *box);
extern void phone_dealloc(int phoneid);
 
/branches/arm/kernel/generic/include/ipc/irq.h
36,7 → 36,7
#define KERN_IPC_IRQ_H_
 
/** Maximum length of IPC IRQ program */
#define IRQ_MAX_PROG_SIZE 10
#define IRQ_MAX_PROG_SIZE 20
 
#include <ipc/ipc.h>
#include <ddi/irq.h>
43,16 → 43,21
#include <arch/types.h>
#include <adt/list.h>
 
extern int ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno,
unative_t method, irq_code_t *ucode);
extern void ipc_irq_send_notif(irq_t *irq);
extern void ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno);
extern void ipc_irq_cleanup(answerbox_t *box);
extern int ipc_irq_register(answerbox_t *, inr_t, devno_t, unative_t,
irq_code_t *);
 
extern irq_ownership_t ipc_irq_top_half_claim(irq_t *);
extern void ipc_irq_top_half_handler(irq_t *);
 
extern int ipc_irq_unregister(answerbox_t *, inr_t, devno_t);
extern void ipc_irq_cleanup(answerbox_t *);
 
/*
* User friendly wrappers for ipc_irq_send_msg(). They are in the form
* ipc_irq_send_msg_m(), where m is the number of payload arguments.
*/
#define ipc_irq_send_msg_0(irq) \
ipc_irq_send_msg((irq), 0, 0, 0, 0, 0)
#define ipc_irq_send_msg_1(irq, a1) \
ipc_irq_send_msg((irq), (a1), 0, 0, 0, 0)
#define ipc_irq_send_msg_2(irq, a1, a2) \
64,8 → 69,8
#define ipc_irq_send_msg_5(irq, a1, a2, a3, a4, a5) \
ipc_irq_send_msg((irq), (a1), (a2), (a3), (a4), (a5))
 
extern void ipc_irq_send_msg(irq_t *irq, unative_t a1, unative_t a2,
unative_t a3, unative_t a4, unative_t a5);
extern void ipc_irq_send_msg(irq_t *, unative_t, unative_t, unative_t, unative_t,
unative_t);
 
#endif
 
/branches/arm/kernel/generic/include/ipc/sysipc.h
53,6 → 53,8
int nonblocking);
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1, unative_t arg2, int mode);
unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid,
ipc_data_t *data, int mode);
unative_t sys_ipc_hangup(int phoneid);
unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method,
irq_code_t *ucode);
/branches/arm/kernel/generic/include/ipc/kbox.h
37,6 → 37,18
 
#include <typedefs.h>
 
/** Kernel answerbox structure. */
typedef struct kbox {
/** The answerbox itself. */
answerbox_t box;
/** Thread used to service the answerbox. */
struct thread *thread;
/** Kbox thread creation vs. begin of cleanup mutual exclusion. */
mutex_t cleanup_lock;
/** True if cleanup of kbox has already started. */
bool finished;
} kbox_t;
 
extern int ipc_connect_kbox(task_id_t);
extern void ipc_kbox_cleanup(void);
 
/branches/arm/kernel/generic/include/sort.h
40,8 → 40,8
/*
* sorting routines
*/
extern void bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b));
extern void qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b));
extern void bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b));
extern void qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b));
 
/*
* default sorting comparators
/branches/arm/kernel/generic/include/macros.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
35,47 → 35,73
#ifndef KERN_MACROS_H_
#define KERN_MACROS_H_
 
#ifndef __ASM__
 
#include <arch/types.h>
 
#define isdigit(d) (((d) >= '0') && ((d) <= '9'))
#define islower(c) (((c) >= 'a') && ((c) <= 'z'))
#define isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
#define isalpha(c) (is_lower((c)) || is_upper((c)))
#define isalphanum(c) (is_alpha((c)) || is_digit((c)))
#define isspace(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || \
((c) == '\r'))
 
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
 
/** Return true if the intervals overlap.
*
* @param s1 Start address of the first interval.
* @param sz1 Size of the first interval.
* @param s2 Start address of the second interval.
* @param sz2 Size of the second interval.
* @param s1 Start address of the first interval.
* @param sz1 Size of the first interval.
* @param s2 Start address of the second interval.
* @param sz2 Size of the second interval.
*/
static inline int overlaps(uintptr_t s1, size_t sz1, uintptr_t s2, size_t sz2)
{
uintptr_t e1 = s1 + sz1;
uintptr_t e2 = s2 + sz2;
 
return (s1 < e2) && (s2 < e1);
return ((s1 < e2) && (s2 < e1));
}
 
#endif /* __ASM__ */
 
#define isdigit(d) (((d) >= '0') && ((d) <= '9'))
#define islower(c) (((c) >= 'a') && ((c) <= 'z'))
#define isupper(c) (((c) >= 'A') && ((c) <= 'Z'))
#define isalpha(c) (is_lower((c)) || is_upper((c)))
#define isalphanum(c) (is_alpha((c)) || is_digit((c)))
#define isspace(c) \
(((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r'))
 
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
 
#define min3(a, b, c) ((a) < (b) ? (min(a, c)) : (min(b, c)))
#define max3(a, b, c) ((a) > (b) ? (max(a, c)) : (max(b, c)))
 
/* Compute overlapping of physical addresses */
#define PA_overlaps(x, szx, y, szy) \
#define PA_overlaps(x, szx, y, szy) \
overlaps(KA2PA((x)), (szx), KA2PA((y)), (szy))
 
#define SIZE2KB(size) ((size) >> 10)
#define SIZE2MB(size) ((size) >> 20)
#define SIZE2KB(size) ((size) >> 10)
#define SIZE2MB(size) ((size) >> 20)
 
#define KB2SIZE(kb) ((kb) << 10)
#define MB2SIZE(mb) ((mb) << 20)
#define KB2SIZE(kb) ((kb) << 10)
#define MB2SIZE(mb) ((mb) << 20)
 
#define STRING(arg) STRING_ARG(arg)
#define STRING_ARG(arg) #arg
#define STRING(arg) STRING_ARG(arg)
#define STRING_ARG(arg) #arg
 
#define LOWER32(arg) ((arg) & 0xffffffff)
#define UPPER32(arg) (((arg) >> 32) & 0xffffffff)
 
#define MERGE_LOUP32(lo, up) \
((((uint64_t) (lo)) & 0xffffffff) \
| ((((uint64_t) (up)) & 0xffffffff) << 32))
 
/** Pseudorandom generator
*
* A pretty standard linear congruential pseudorandom
* number generator (m = 2^32 or 2^64 depending on architecture).
*
*/
#define RANDI(seed) \
({ \
(seed) = 1103515245 * (seed) + 12345; \
(seed); \
})
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/sysinfo/sysinfo.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
36,6 → 36,7
#define KERN_SYSINFO_H_
 
#include <arch/types.h>
#include <string.h>
 
typedef union sysinfo_item_val {
unative_t val;
59,13 → 60,13
int subinfo_type;
} sysinfo_item_t;
 
#define SYSINFO_VAL_VAL 0
#define SYSINFO_VAL_FUNCTION 1
#define SYSINFO_VAL_UNDEFINED '?'
#define SYSINFO_VAL_VAL 0
#define SYSINFO_VAL_FUNCTION 1
#define SYSINFO_VAL_UNDEFINED U_SPECIAL
 
#define SYSINFO_SUBINFO_NONE 0
#define SYSINFO_SUBINFO_TABLE 1
#define SYSINFO_SUBINFO_FUNCTION 2
#define SYSINFO_SUBINFO_NONE 0
#define SYSINFO_SUBINFO_TABLE 1
#define SYSINFO_SUBINFO_FUNCTION 2
 
typedef unative_t (*sysinfo_val_fn_t)(sysinfo_item_t *root);
typedef unative_t (*sysinfo_subinfo_fn_t)(const char *subname);
/branches/arm/kernel/generic/include/printf/printf_core.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
35,20 → 35,23
#ifndef KERN_PRINTF_CORE_H_
#define KERN_PRINTF_CORE_H_
 
#include <arch/types.h>
#include <typedefs.h>
#include <arch/arg.h>
 
/** Structure for specifying output methods for different printf clones. */
struct printf_spec {
/* Output function, returns count of printed characters or EOF */
int (*write)(void *, size_t, void *);
/* Support data - output stream specification, its state, locks,... */
typedef struct {
/* String output function, returns number of printed characters or EOF */
int (*str_write)(const char *, size_t, void *);
/* Wide string output function, returns number of printed characters or EOF */
int (*wstr_write)(const wchar_t *, size_t, void *);
/* User data - output stream specification, state, locks, etc. */
void *data;
} printf_spec_t;
 
};
int printf_core(const char *fmt, printf_spec_t *ps, va_list ap);
 
int printf_core(const char *fmt, struct printf_spec *ps, va_list ap);
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/print.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
46,11 → 46,9
 
extern int puts(const char *s);
extern int printf(const char *fmt, ...);
extern int sprintf(char *str, const char *fmt, ...);
extern int snprintf(char *str, size_t size, const char *fmt, ...);
 
extern int vprintf(const char *fmt, va_list ap);
extern int vsprintf(char *str, const char *fmt, va_list ap);
extern int vsnprintf(char *str, size_t size, const char *fmt, va_list ap);
 
#endif
/branches/arm/kernel/generic/include/putchar.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
35,7 → 35,7
#ifndef KERN_PUTCHAR_H_
#define KERN_PUTCHAR_H_
 
extern void putchar(const char ch);
extern void putchar(const wchar_t ch);
 
#endif
 
/branches/arm/kernel/generic/include/syscall/syscall.h
44,6 → 44,7
SYS_THREAD_GET_ID,
SYS_TASK_GET_ID,
SYS_TASK_SET_NAME,
SYS_PROGRAM_SPAWN_LOADER,
SYS_FUTEX_SLEEP,
62,14 → 63,18
SYS_IPC_ANSWER_FAST,
SYS_IPC_ANSWER_SLOW,
SYS_IPC_FORWARD_FAST,
SYS_IPC_FORWARD_SLOW,
SYS_IPC_WAIT,
SYS_IPC_HANGUP,
SYS_IPC_REGISTER_IRQ,
SYS_IPC_UNREGISTER_IRQ,
 
SYS_EVENT_SUBSCRIBE,
SYS_CAP_GRANT,
SYS_CAP_REVOKE,
SYS_DEVICE_ASSIGN_DEVNO,
SYS_PHYSMEM_MAP,
SYS_IOSPACE_ENABLE,
SYS_PREEMPT_CONTROL,
78,6 → 83,7
SYS_SYSINFO_VALUE,
SYS_DEBUG_ENABLE_CONSOLE,
SYS_DEBUG_DISABLE_CONSOLE,
SYS_IPC_CONNECT_KBOX,
SYSCALL_END
} syscall_t;
/branches/arm/kernel/generic/include/typedefs.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
51,6 → 51,12
typedef int32_t inr_t;
typedef int32_t devno_t;
 
typedef int32_t wchar_t;
 
typedef volatile uint8_t ioport8_t;
typedef volatile uint16_t ioport16_t;
typedef volatile uint32_t ioport32_t;
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/errno.h
48,15 → 48,18
* sys_ipc_hangup() to close the connection.
* Used by answerbox to close the connection.
*/
#define EEXISTS -8 /* Entry already exists */
#define EBADMEM -9 /* Bad memory pointer */
#define ENOTSUP -10 /* Not supported */
#define EADDRNOTAVAIL -11 /* Address not available. */
#define ETIMEOUT -12 /* Timeout expired */
#define EINVAL -13 /* Invalid value */
#define EBUSY -14 /* Resource is busy */
#define EOVERFLOW -15 /* The result does not fit its size. */
#define EINTR -16 /* Operation was interrupted. */
#define EPARTY -8 /* The other party encountered an error when
* receiving the call.
*/
#define EEXISTS -9 /* Entry already exists */
#define EBADMEM -10 /* Bad memory pointer */
#define ENOTSUP -11 /* Not supported */
#define EADDRNOTAVAIL -12 /* Address not available. */
#define ETIMEOUT -13 /* Timeout expired */
#define EINVAL -14 /* Invalid value */
#define EBUSY -15 /* Resource is busy */
#define EOVERFLOW -16 /* The result does not fit its size. */
#define EINTR -17 /* Operation was interrupted. */
 
#endif
 
/branches/arm/kernel/generic/include/func.h
41,11 → 41,6
extern atomic_t haltstate;
 
extern void halt(void);
 
extern size_t strlen(const char *str);
extern int strcmp(const char *src, const char *dst);
extern int strncmp(const char *src, const char *dst, size_t len);
extern void strncpy(char *dest, const char *src, size_t len);
extern unative_t atoi(const char *text);
extern void order(const uint64_t val, uint64_t *rv, char *suffix);
 
/branches/arm/kernel/generic/include/memstr.h
44,7 → 44,7
extern void *_memcpy(void *dst, const void *src, size_t cnt);
extern void _memsetb(void *dst, size_t cnt, uint8_t x);
extern void _memsetw(void *dst, size_t cnt, uint16_t x);
extern char *strcpy(char *dest, const char *src);
extern void *memmove(void *dst, const void *src, size_t cnt);
 
#endif
 
/branches/arm/kernel/generic/include/main/main.h
35,8 → 35,13
#ifndef KERN_MAIN_H_
#define KERN_MAIN_H_
 
#include <arch/types.h>
 
extern uintptr_t stack_safe;
 
extern void main_bsp(void);
extern void main_ap(void);
 
#endif
 
/** @}
/branches/arm/kernel/generic/include/align.h
26,13 → 26,13
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @ingroup others
* @{
*/
/**
* @file
* @brief Macros for making values and addresses aligned.
* @brief Macros for making values and addresses aligned.
*/
 
#ifndef KERN_ALIGN_H_
43,7 → 43,7
* @param s Address or size to be aligned.
* @param a Size of alignment, must be power of 2.
*/
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1))
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1))
 
 
/** Align to the nearest higher address.
51,7 → 51,7
* @param s Address or size to be aligned.
* @param a Size of alignment, must be power of 2.
*/
#define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1))
#define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1))
 
#endif
 
/branches/arm/kernel/generic/include/fpu_context.h
37,10 → 37,6
 
#include <arch/fpu_context.h>
 
#if defined(CONFIG_FPU_LAZY) && !defined(ARCH_HAS_FPU)
# error "CONFIG_FPU_LAZY defined, but no ARCH_HAS_FPU"
#endif
 
extern void fpu_context_save(fpu_context_t *);
extern void fpu_context_restore(fpu_context_t *);
extern void fpu_init(void);
/branches/arm/kernel/generic/include/interrupt.h
44,12 → 44,12
 
typedef void (* iroutine)(int n, istate_t *istate);
 
#define fault_if_from_uspace(istate, cmd, ...) \
#define fault_if_from_uspace(istate, fmt, ...) \
{ \
if (istate_from_uspace(istate)) { \
task_t *task = TASK; \
printf("Task %" PRIu64 " killed due to an exception at %p.", task->taskid, istate_get_pc(istate)); \
printf(" " cmd, ##__VA_ARGS__); \
printf("Task %s (%" PRIu64 ") killed due to an exception at %p: ", task->name, task->taskid, istate_get_pc(istate)); \
printf(fmt "\n", ##__VA_ARGS__); \
task_kill(task->taskid); \
thread_exit(); \
} \
/branches/arm/kernel/generic/include/debug.h
57,21 → 57,21
#ifdef CONFIG_DEBUG
# define ASSERT(expr) \
if (!(expr)) { \
panic("assertion failed (%s), caller=%p\n", #expr, CALLER); \
panic("Assertion failed (%s), caller=%p.", #expr, CALLER); \
}
#else
# define ASSERT(expr)
#endif
 
/** Extensive debugging output macro
/** Extensive logging output macro
*
* If CONFIG_EDEBUG is set, the LOG() macro
* If CONFIG_LOG is set, the LOG() macro
* will print whatever message is indicated plus
* an information about the location.
*
*/
 
#ifdef CONFIG_EDEBUG
#ifdef CONFIG_LOG
# define LOG(format, ...) \
printf("%s() at %s:%u: " format "\n", __func__, __FILE__, \
__LINE__, ##__VA_ARGS__);
79,15 → 79,15
# define LOG(format, ...)
#endif
 
/** Extensive debugging execute macro
/** Extensive logging execute macro
*
* If CONFIG_EDEBUG is set, the LOG_EXEC() macro
* If CONFIG_LOG is set, the LOG_EXEC() macro
* will print an information about calling a given
* function and call it.
*
*/
 
#ifdef CONFIG_EDEBUG
#ifdef CONFIG_LOG
# define LOG_EXEC(fnc) \
{ \
printf("%s() at %s:%u: " #fnc "\n", __func__, __FILE__, \
/branches/arm/kernel/generic/include/panic.h
37,11 → 37,11
 
#ifdef CONFIG_DEBUG
# define panic(format, ...) \
panic_printf("Kernel panic in %s() at %s:%u: " format, __func__, \
__FILE__, __LINE__, ##__VA_ARGS__);
panic_printf("Kernel panic in %s() at %s:%u: " format "\n", \
__func__, __FILE__, __LINE__, ##__VA_ARGS__);
#else
# define panic(format, ...) \
panic_printf("Kernel panic: " format, ##__VA_ARGS__);
panic_printf("Kernel panic: " format "\n", ##__VA_ARGS__);
#endif
 
extern void panic_printf(char *fmt, ...) __attribute__((noreturn));
/branches/arm/kernel/generic/include/udebug/udebug.h
147,9 → 147,7
/** BEGIN operation in progress (waiting for threads to stop) */
UDEBUG_TS_BEGINNING,
/** Debugger fully connected */
UDEBUG_TS_ACTIVE,
/** Task is shutting down, no more debug activities allowed */
UDEBUG_TS_SHUTDOWN
UDEBUG_TS_ACTIVE
} udebug_task_state_t;
 
/** Debugging part of task_t structure.
169,25 → 167,19
/** Debugging part of thread_t structure.
*/
typedef struct {
/**
* Prevent deadlock with udebug_before_thread_runs() in interrupt
* handler, without actually disabling interrupts.
* ==0 means "unlocked", >0 means "locked"
*/
atomic_t int_lock;
 
/** Synchronize debug ops on this thread / access to this structure */
/** Synchronize debug ops on this thread / access to this structure. */
mutex_t lock;
 
waitq_t go_wq;
call_t *go_call;
unative_t syscall_args[6];
istate_t *uspace_state;
 
/** What type of event are we stopped in or 0 if none */
udebug_event_t cur_event;
bool stop;
bool stoppable;
bool debug_active; /**< In a debugging session */
/** What type of event are we stopped in or 0 if none. */
udebug_event_t cur_event;
bool go; /**< thread is GO */
bool stoppable; /**< thread is stoppable */
bool active; /**< thread is in a debugging session */
} udebug_thread_t;
 
struct task;
200,7 → 192,7
unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc,
bool end_variant);
 
void udebug_thread_b_event(struct thread *t);
void udebug_thread_b_event_attach(struct thread *t, struct task *ta);
void udebug_thread_e_event(void);
 
void udebug_stoppable_begin(void);
/branches/arm/kernel/generic/include/stdarg.h
45,7 → 45,7
#define va_start(ap, last) __builtin_va_start(ap, last)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
#define va_end(ap) __builtin_va_end(ap)
#define va_copy(dst,src) __builtin_va_copy(dst,src)
#define va_copy(dst, src) __builtin_va_copy(dst, src)
 
#endif
 
/branches/arm/kernel/generic/src/main/uinit.c
79,6 → 79,14
uarg.uspace_thread_arg = NULL;
 
free((uspace_arg_t *) arg);
/*
* Disable interrupts so that the execution of userspace() is not
* disturbed by any interrupts as some of the userspace()
* implementations will switch to the userspace stack before switching
* the mode.
*/
(void) interrupts_disable();
userspace(&uarg);
}
 
/branches/arm/kernel/generic/src/main/kinit.c
32,7 → 32,7
 
/**
* @file
* @brief Kernel initialization thread.
* @brief Kernel initialization thread.
*
* This file contains kinit kernel thread which carries out
* high level system initialization.
64,6 → 64,8
#include <security/cap.h>
#include <lib/rd.h>
#include <ipc/ipc.h>
#include <debug.h>
#include <string.h>
 
#ifdef CONFIG_SMP
#include <smp/smp.h>
72,6 → 74,15
#include <synch/waitq.h>
#include <synch/spinlock.h>
 
#define ALIVE_CHARS 4
 
#ifdef CONFIG_KCONSOLE
static char alive[ALIVE_CHARS] = "-\\|/";
#endif
 
#define INIT_PREFIX "init:"
#define INIT_PREFIX_LEN 5
 
/** Kernel initialization thread.
*
* kinit takes care of higher level kernel
82,16 → 93,19
*/
void kinit(void *arg)
{
thread_t *t;
 
#if defined(CONFIG_SMP) || defined(CONFIG_KCONSOLE)
thread_t *thread;
#endif
/*
* Detach kinit as nobody will call thread_join_timeout() on it.
*/
thread_detach(THREAD);
 
interrupts_disable();
 
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
if (config.cpu_count > 1) {
waitq_initialize(&ap_completion_wq);
/*
100,78 → 114,90
* not mess together with kcpulb threads.
* Just a beautification.
*/
if ((t = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED,
"kmp", true))) {
spinlock_lock(&t->lock);
t->cpu = &cpus[0];
spinlock_unlock(&t->lock);
thread_ready(t);
thread = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED, "kmp", true);
if (thread != NULL) {
spinlock_lock(&thread->lock);
thread->cpu = &cpus[0];
spinlock_unlock(&thread->lock);
thread_ready(thread);
} else
panic("thread_create/kmp\n");
thread_join(t);
thread_detach(t);
panic("Unable to create kmp thread.");
thread_join(thread);
thread_detach(thread);
}
#endif /* CONFIG_SMP */
/*
* Now that all CPUs are up, we can report what we've found.
*/
cpu_list();
 
#ifdef CONFIG_SMP
if (config.cpu_count > 1) {
count_t i;
size_t i;
/*
* For each CPU, create its load balancing thread.
*/
for (i = 0; i < config.cpu_count; i++) {
 
if ((t = thread_create(kcpulb, NULL, TASK,
THREAD_FLAG_WIRED, "kcpulb", true))) {
spinlock_lock(&t->lock);
t->cpu = &cpus[i];
spinlock_unlock(&t->lock);
thread_ready(t);
thread = thread_create(kcpulb, NULL, TASK, THREAD_FLAG_WIRED, "kcpulb", true);
if (thread != NULL) {
spinlock_lock(&thread->lock);
thread->cpu = &cpus[i];
spinlock_unlock(&thread->lock);
thread_ready(thread);
} else
panic("thread_create/kcpulb\n");
 
printf("Unable to create kcpulb thread for cpu" PRIs "\n", i);
}
}
#endif /* CONFIG_SMP */
 
/*
* At this point SMP, if present, is configured.
*/
arch_post_smp_init();
 
/*
* Create kernel console.
*/
t = thread_create(kconsole, (void *) "kconsole", TASK, 0, "kconsole",
false);
if (t)
thread_ready(t);
else
panic("thread_create/kconsole\n");
 
#ifdef CONFIG_KCONSOLE
if (stdin) {
/*
* Create kernel console.
*/
thread = thread_create(kconsole_thread, NULL, TASK, 0, "kconsole", false);
if (thread != NULL)
thread_ready(thread);
else
printf("Unable to create kconsole thread\n");
}
#endif /* CONFIG_KCONSOLE */
interrupts_enable();
/*
* Create user tasks, load RAM disk images.
*/
count_t i;
size_t i;
program_t programs[CONFIG_INIT_TASKS];
for (i = 0; i < init.cnt; i++) {
if (init.tasks[i].addr % FRAME_SIZE) {
printf("init[%" PRIc "].addr is not frame aligned", i);
printf("init[%" PRIs "].addr is not frame aligned\n", i);
continue;
}
/*
* Construct task name from the 'init:' prefix and the
* name stored in the init structure (if any).
*/
char namebuf[TASK_NAME_BUFLEN];
char *name;
name = init.tasks[i].name;
if (name[0] == 0)
name = "<unknown>";
ASSERT(TASK_NAME_BUFLEN >= INIT_PREFIX_LEN);
str_cpy(namebuf, TASK_NAME_BUFLEN, INIT_PREFIX);
str_cpy(namebuf + INIT_PREFIX_LEN,
TASK_NAME_BUFLEN - INIT_PREFIX_LEN, name);
 
int rc = program_create_from_image((void *) init.tasks[i].addr,
&programs[i]);
 
if (rc == 0 && programs[i].task != NULL) {
namebuf, &programs[i]);
if ((rc == 0) && (programs[i].task != NULL)) {
/*
* Set capabilities to init userspace tasks.
*/
184,31 → 210,34
/* It was the program loader and was registered */
} else {
/* RAM disk image */
int rd = init_rd((rd_header_t *) init.tasks[i].addr,
init.tasks[i].size);
int rd = init_rd((rd_header_t *) init.tasks[i].addr, init.tasks[i].size);
if (rd != RE_OK)
printf("Init binary %" PRIc " not used, error "
"code %d.\n", i, rd);
printf("Init binary %" PRIs " not used (error %d)\n", i, rd);
}
}
/*
* Run user tasks with reasonable delays
* Run user tasks.
*/
for (i = 0; i < init.cnt; i++) {
if (programs[i].task != NULL) {
thread_usleep(50000);
if (programs[i].task != NULL)
program_ready(&programs[i]);
}
}
 
#ifdef CONFIG_KCONSOLE
if (!stdin) {
while (1) {
thread_sleep(10);
printf("kinit: No stdin\nKernel alive: .");
unsigned int i = 0;
while (true) {
printf("\b%c", alive[i % ALIVE_CHARS]);
thread_sleep(1);
printf("kinit... ");
i++;
}
}
#endif /* CONFIG_KCONSOLE */
}
 
/** @}
/branches/arm/kernel/generic/src/main/main.c
32,7 → 32,7
 
/**
* @file
* @brief Main initialization kernel function for all processors.
* @brief Main initialization kernel function for all processors.
*
* During kernel boot, all processors, after architecture dependent
* initialization, start executing code found in this file. After
81,8 → 81,9
#include <adt/btree.h>
#include <smp/smp.h>
#include <ddi/ddi.h>
#include <main/main.h>
#include <ipc/event.h>
 
 
/** Global configuration structure. */
config_t config;
 
105,18 → 106,15
* appropriate sizes and addresses.
*/
 
/**< Virtual address of where the kernel is loaded. */
/** Virtual address of where the kernel is loaded. */
uintptr_t hardcoded_load_address = 0;
/**< Size of the kernel code in bytes. */
/** Size of the kernel code in bytes. */
size_t hardcoded_ktext_size = 0;
/**< Size of the kernel data in bytes. */
/** Size of the kernel data in bytes. */
size_t hardcoded_kdata_size = 0;
/**< Lowest safe stack virtual address. */
/** Lowest safe stack virtual address. */
uintptr_t stack_safe = 0;
 
void main_bsp(void);
void main_ap(void);
 
/*
* These two functions prevent stack from underflowing during the
* kernel boot phase when SP is set to the very top of the reserved
155,7 → 153,7
config.stack_base = config.base + config.kernel_size;
/* Avoid placing stack on top of init */
count_t i;
size_t i;
for (i = 0; i < init.cnt; i++) {
if (PA_overlaps(config.stack_base, config.stack_size,
init.tasks[i].addr, init.tasks[i].size))
191,8 → 189,6
{
/* Keep this the first thing. */
the_initialize(THE);
 
LOG();
version_print();
201,7 → 197,7
config.base, config.kernel_size, config.stack_base,
config.stack_size);
 
#ifdef CONFIG_KCONSOLE
/*
* kconsole data structures must be initialized very early
* because other subsystems will register their respective
208,6 → 204,7
* commands.
*/
LOG_EXEC(kconsole_init());
#endif
/*
* Exception handler initialization, before architecture
214,7 → 211,7
* starts adding its own handlers
*/
LOG_EXEC(exc_init());
 
/*
* Memory management subsystems initialization.
*/
236,7 → 233,7
/* Slab must be initialized after we know the number of processors. */
LOG_EXEC(slab_enable_cpucache());
printf("Detected %" PRIc " CPU(s), %" PRIu64" MiB free memory\n",
printf("Detected %" PRIs " CPU(s), %" PRIu64" MiB free memory\n",
config.cpu_count, SIZE2MB(zone_total_size()));
LOG_EXEC(cpu_init());
250,31 → 247,32
LOG_EXEC(futex_init());
if (init.cnt > 0) {
count_t i;
size_t i;
for (i = 0; i < init.cnt; i++)
printf("init[%" PRIc "].addr=%#" PRIp ", init[%" PRIc
"].size=%#" PRIs "\n", i, init.tasks[i].addr, i,
LOG("init[%" PRIs "].addr=%#" PRIp ", init[%" PRIs
"].size=%#" PRIs, i, init.tasks[i].addr, i,
init.tasks[i].size);
} else
printf("No init binaries found\n");
printf("No init binaries found.\n");
LOG_EXEC(ipc_init());
LOG_EXEC(event_init());
LOG_EXEC(klog_init());
 
/*
* Create kernel task.
*/
task_t *kernel = task_create(AS_KERNEL, "kernel");
if (!kernel)
panic("Can't create kernel task\n");
panic("Cannot create kernel task.");
/*
* Create the first thread.
*/
thread_t *kinit_thread = thread_create(kinit, NULL, kernel, 0, "kinit",
true);
thread_t *kinit_thread
= thread_create(kinit, NULL, kernel, 0, "kinit", true);
if (!kinit_thread)
panic("Can't create kinit thread\n");
panic("Cannot create kinit thread.");
LOG_EXEC(thread_ready(kinit_thread));
/*
328,6 → 326,7
* collide with another CPU coming up. To prevent this, we
* switch to this cpu's private stack prior to waking kmp up.
*/
context_save(&CPU->saved_context);
context_set(&CPU->saved_context, FADDR(main_ap_separated_stack),
(uintptr_t) CPU->stack, CPU_STACK_SIZE);
context_restore(&CPU->saved_context);
/branches/arm/kernel/generic/src/main/shutdown.c
32,10 → 32,11
 
/**
* @file
* @brief Shutdown procedures.
* @brief Shutdown procedures.
*/
 
#include <arch.h>
#include <func.h>
#include <print.h>
 
void reboot(void)
47,6 → 48,7
#endif
arch_reboot();
halt();
}
 
/** @}
/branches/arm/kernel/generic/src/main/version.c
34,21 → 34,22
 
#include <main/version.h>
#include <print.h>
#include <macros.h>
 
char *project = "SPARTAN kernel";
char *copyright = "Copyright (c) 2001-2009 HelenOS project";
char *release = RELEASE;
char *name = NAME;
char *arch = ARCH;
char *release = STRING(RELEASE);
char *name = STRING(NAME);
char *arch = STRING(KARCH);
 
#ifdef REVISION
char *revision = ", revision " REVISION;
char *revision = ", revision " STRING(REVISION);
#else
char *revision = "";
#endif
 
#ifdef TIMESTAMP
char *timestamp = " on " TIMESTAMP;
char *timestamp = " on " STRING(TIMESTAMP);
#else
char *timestamp = "";
#endif
/branches/arm/kernel/generic/src/printf/sprintf.c
File deleted
/branches/arm/kernel/generic/src/printf/vsprintf.c
File deleted
/branches/arm/kernel/generic/src/printf/printf_core.c
1,6 → 1,7
/*
* Copyright (c) 2001-2004 Jakub Jermar
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
27,38 → 28,37
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/**
* @file
* @brief Printing functions.
* @brief Printing functions.
*/
 
#include <printf/printf_core.h>
#include <putchar.h>
#include <print.h>
#include <arch/arg.h>
#include <macros.h>
#include <func.h>
#include <string.h>
#include <arch.h>
 
/** show prefixes 0x or 0 */
#define __PRINTF_FLAG_PREFIX 0x00000001
#define __PRINTF_FLAG_PREFIX 0x00000001
/** signed / unsigned number */
#define __PRINTF_FLAG_SIGNED 0x00000002
#define __PRINTF_FLAG_SIGNED 0x00000002
/** print leading zeroes */
#define __PRINTF_FLAG_ZEROPADDED 0x00000004
#define __PRINTF_FLAG_ZEROPADDED 0x00000004
/** align to left */
#define __PRINTF_FLAG_LEFTALIGNED 0x00000010
#define __PRINTF_FLAG_LEFTALIGNED 0x00000010
/** always show + sign */
#define __PRINTF_FLAG_SHOWPLUS 0x00000020
#define __PRINTF_FLAG_SHOWPLUS 0x00000020
/** print space instead of plus */
#define __PRINTF_FLAG_SPACESIGN 0x00000040
#define __PRINTF_FLAG_SPACESIGN 0x00000040
/** show big characters */
#define __PRINTF_FLAG_BIGCHARS 0x00000080
#define __PRINTF_FLAG_BIGCHARS 0x00000080
/** number has - sign */
#define __PRINTF_FLAG_NEGATIVE 0x00000100
#define __PRINTF_FLAG_NEGATIVE 0x00000100
 
/**
* Buffer big enough for 64-bit number printed in base 2, sign, prefix and 0
65,7 → 65,7
* to terminate string... (last one is only for better testing end of buffer by
* zero-filling subroutine)
*/
#define PRINT_NUMBER_BUFFER_SIZE (64 + 5)
#define PRINT_NUMBER_BUFFER_SIZE (64 + 5)
 
/** Enumeration of possible arguments types.
*/
78,69 → 78,103
PrintfQualifierPointer
} qualifier_t;
 
static char nullstr[] = "(NULL)";
static char digits_small[] = "0123456789abcdef";
static char digits_big[] = "0123456789ABCDEF";
static char invalch = U_SPECIAL;
 
/** Print one or more characters without adding newline.
*
* @param buf Buffer with size at least count bytes. NULL pointer is
* not allowed!
* @param count Number of characters to print.
* @param ps Output method and its data.
* @return Number of characters printed.
* @param buf Buffer holding characters with size of
* at least size bytes. NULL is not allowed!
* @param size Size of the buffer in bytes.
* @param ps Output method and its data.
*
* @return Number of characters printed.
*
*/
static int printf_putnchars(const char * buf, size_t count,
struct printf_spec *ps)
static int printf_putnchars(const char *buf, size_t size,
printf_spec_t *ps)
{
return ps->write((void *) buf, count, ps->data);
return ps->str_write((void *) buf, size, ps->data);
}
 
/** Print a string without adding a newline.
/** Print one or more wide characters without adding newline.
*
* @param str String to print.
* @param ps Write function specification and support data.
* @return Number of characters printed.
* @param buf Buffer holding wide characters with size of
* at least size bytes. NULL is not allowed!
* @param size Size of the buffer in bytes.
* @param ps Output method and its data.
*
* @return Number of wide characters printed.
*
*/
static int printf_putstr(const char * str, struct printf_spec *ps)
static int printf_wputnchars(const wchar_t *buf, size_t size,
printf_spec_t *ps)
{
size_t count;
return ps->wstr_write((void *) buf, size, ps->data);
}
 
/** Print string without adding a newline.
*
* @param str String to print.
* @param ps Write function specification and support data.
*
* @return Number of characters printed.
*
*/
static int printf_putstr(const char *str, printf_spec_t *ps)
{
if (str == NULL)
return printf_putnchars(nullstr, str_size(nullstr), ps);
if (str == NULL) {
char *nullstr = "(NULL)";
return printf_putnchars(nullstr, strlen(nullstr), ps);
}
return ps->str_write((void *) str, str_size(str), ps->data);
}
 
count = strlen(str);
 
return ps->write((void *) str, count, ps->data);
/** Print one ASCII character.
*
* @param c ASCII character to be printed.
* @param ps Output method.
*
* @return Number of characters printed.
*
*/
static int printf_putchar(const char ch, printf_spec_t *ps)
{
if (!ascii_check(ch))
return ps->str_write((void *) &invalch, 1, ps->data);
return ps->str_write(&ch, 1, ps->data);
}
 
/** Print one character.
/** Print one wide character.
*
* @param c Character to be printed.
* @param ps Output method.
* @param c Wide character to be printed.
* @param ps Output method.
*
* @return Number of characters printed.
* @return Number of characters printed.
*
*/
static int printf_putchar(int c, struct printf_spec *ps)
static int printf_putwchar(const wchar_t ch, printf_spec_t *ps)
{
unsigned char ch = c;
if (!chr_check(ch))
return ps->str_write((void *) &invalch, 1, ps->data);
return ps->write((void *) &ch, 1, ps->data);
return ps->wstr_write(&ch, sizeof(wchar_t), ps->data);
}
 
/** Print one formatted character.
/** Print one formatted ASCII character.
*
* @param c Character to print.
* @param width Width modifier.
* @param flags Flags that change the way the character is printed.
* @param ch Character to print.
* @param width Width modifier.
* @param flags Flags that change the way the character is printed.
*
* @return Number of characters printed, negative value on failure.
* @return Number of characters printed, negative value on failure.
*
*/
static int print_char(char c, int width, uint64_t flags, struct printf_spec *ps)
static int print_char(const char ch, int width, uint32_t flags, printf_spec_t *ps)
{
int counter = 0;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (--width > 0) {
/*
147,106 → 181,190
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
++counter;
if (printf_putchar(' ', ps) > 0)
counter++;
}
}
if (printf_putchar(c, ps) > 0)
if (printf_putchar(ch, ps) > 0)
counter++;
while (--width > 0) {
/*
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
counter++;
}
return (int) (counter + 1);
}
 
while (--width > 0) {
/** Print one formatted wide character.
*
* @param ch Character to print.
* @param width Width modifier.
* @param flags Flags that change the way the character is printed.
*
* @return Number of characters printed, negative value on failure.
*
*/
static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
{
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (--width > 0) {
/*
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
counter++;
}
}
if (printf_putwchar(ch, ps) > 0)
counter++;
while (--width > 0) {
/*
* One space is consumed by the character itself, hence
* the predecrement.
*/
if (printf_putchar(' ', ps) > 0)
++counter;
counter++;
}
return ++counter;
return (int) (counter + 1);
}
 
/** Print string.
*
* @param s String to be printed.
* @param width Width modifier.
* @param precision Precision modifier.
* @param flags Flags that modify the way the string is printed.
* @param str String to be printed.
* @param width Width modifier.
* @param precision Precision modifier.
* @param flags Flags that modify the way the string is printed.
*
* @return Number of characters printed, negative value on failure.
*/
static int print_string(char *s, int width, unsigned int precision,
uint64_t flags, struct printf_spec *ps)
* @return Number of characters printed, negative value on failure.
*/
static int print_str(char *str, int width, unsigned int precision,
uint32_t flags, printf_spec_t *ps)
{
int counter = 0;
size_t size;
if (str == NULL)
return printf_putstr(nullstr, ps);
 
/* Print leading spaces. */
size_t strw = str_length(str);
if (precision == 0)
precision = strw;
 
/* Left padding */
size_t counter = 0;
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
}
 
/* Part of @a str fitting into the alloted space. */
int retval;
size_t size = str_lsize(str, precision);
if ((retval = printf_putnchars(str, size, ps)) < 0)
return -counter;
 
if (s == NULL) {
return printf_putstr("(NULL)", ps);
counter += retval;
 
/* Right padding */
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
size = strlen(s);
 
/* print leading spaces */
return ((int) counter);
 
if (precision == 0)
precision = size;
}
 
/** Print wide string.
*
* @param str Wide string to be printed.
* @param width Width modifier.
* @param precision Precision modifier.
* @param flags Flags that modify the way the string is printed.
*
* @return Number of wide characters printed, negative value on failure.
*/
static int print_wstr(wchar_t *str, int width, unsigned int precision,
uint32_t flags, printf_spec_t *ps)
{
if (str == NULL)
return printf_putstr(nullstr, ps);
/* Print leading spaces. */
size_t strw = wstr_length(str);
if (precision == 0)
precision = strw;
/* Left padding */
size_t counter = 0;
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
}
 
if ((retval = printf_putnchars(s, min(size, precision), ps)) < 0) {
/* Part of @a wstr fitting into the alloted space. */
int retval;
size_t size = wstr_lsize(str, precision);
if ((retval = printf_wputnchars(str, size, ps)) < 0)
return -counter;
counter += retval;
/* Right padding */
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
counter += retval;
 
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
++counter;
}
return counter;
return ((int) counter);
}
 
 
/** Print a number in a given base.
*
* Print significant digits of a number in given base.
*
* @param num Number to print.
* @param widt Width modifier.h
* @param precision Precision modifier.
* @param base Base to print the number in (must be between 2 and 16).
* @param flags Flags that modify the way the number is printed.
* @param num Number to print.
* @param width Width modifier.
* @param precision Precision modifier.
* @param base Base to print the number in (must be between 2 and 16).
* @param flags Flags that modify the way the number is printed.
*
* @return Number of characters printed.
* @return Number of characters printed.
*
*/
static int print_number(uint64_t num, int width, int precision, int base,
uint64_t flags, struct printf_spec *ps)
uint32_t flags, printf_spec_t *ps)
{
char *digits = digits_small;
char d[PRINT_NUMBER_BUFFER_SIZE];
char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
int size = 0; /* size of number with all prefixes and signs */
int number_size; /* size of plain number */
char sgn;
int retval;
int counter = 0;
char *digits;
if (flags & __PRINTF_FLAG_BIGCHARS)
digits = digits_big;
else
digits = digits_small;
if (flags & __PRINTF_FLAG_BIGCHARS)
digits = digits_big;
char data[PRINT_NUMBER_BUFFER_SIZE];
char *ptr = &data[PRINT_NUMBER_BUFFER_SIZE - 1];
*ptr-- = 0; /* Put zero at end of string */
 
/* Size of number with all prefixes and signs */
int size = 0;
/* Put zero at end of string */
*ptr-- = 0;
if (num == 0) {
*ptr-- = '0';
size++;
257,15 → 375,17
} while (num /= base);
}
number_size = size;
 
/* Size of plain number */
int number_size = size;
/*
* Collect the sum of all prefixes/signs/... to calculate padding and
* Collect the sum of all prefixes/signs/etc. to calculate padding and
* leading zeroes.
*/
if (flags & __PRINTF_FLAG_PREFIX) {
switch(base) {
case 2: /* Binary formating is not standard, but usefull */
case 2:
/* Binary formating is not standard, but usefull */
size += 2;
break;
case 8:
276,8 → 396,8
break;
}
}
 
sgn = 0;
char sgn = 0;
if (flags & __PRINTF_FLAG_SIGNED) {
if (flags & __PRINTF_FLAG_NEGATIVE) {
sgn = '-';
290,48 → 410,46
size++;
}
}
 
if (flags & __PRINTF_FLAG_LEFTALIGNED) {
if (flags & __PRINTF_FLAG_LEFTALIGNED)
flags &= ~__PRINTF_FLAG_ZEROPADDED;
}
 
/*
* If the number is leftaligned or precision is specified then
* zeropadding is ignored.
* If the number is left-aligned or precision is specified then
* padding with zeros is ignored.
*/
if (flags & __PRINTF_FLAG_ZEROPADDED) {
if ((precision == 0) && (width > size)) {
if ((precision == 0) && (width > size))
precision = width - size + number_size;
}
}
 
/* print leading spaces */
/* Print leading spaces */
if (number_size > precision) {
/* print the whole number not only a part */
/* Print the whole number, not only a part */
precision = number_size;
}
 
width -= precision + size - number_size;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
}
/* print sign */
/* Print sign */
if (sgn) {
if (printf_putchar(sgn, ps) == 1)
counter++;
}
/* print prefix */
/* Print prefix */
if (flags & __PRINTF_FLAG_PREFIX) {
switch(base) {
case 2: /* Binary formating is not standard, but usefull */
case 2:
/* Binary formating is not standard, but usefull */
if (printf_putchar('0', ps) == 1)
counter++;
if (flags & __PRINTF_FLAG_BIGCHARS) {
359,150 → 477,154
break;
}
}
 
/* print leading zeroes */
/* Print leading zeroes */
precision -= number_size;
while (precision-- > 0) {
while (precision-- > 0) {
if (printf_putchar('0', ps) == 1)
counter++;
}
 
/* print number itself */
 
if ((retval = printf_putstr(++ptr, ps)) > 0) {
/* Print the number itself */
int retval;
if ((retval = printf_putstr(++ptr, ps)) > 0)
counter += retval;
}
/* print ending spaces */
/* Print tailing spaces */
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
while (width-- > 0) {
if (printf_putchar(' ', ps) == 1)
counter++;
}
 
return counter;
return ((int) counter);
}
 
 
/** Print formatted string.
*
* Print string formatted according to the fmt parameter and variadic arguments.
* Each formatting directive must have the following form:
*
* \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
*
* \% [ FLAGS ] [ WIDTH ] [ .PRECISION ] [ TYPE ] CONVERSION
*
* FLAGS:@n
* - "#" Force to print prefix.For \%o conversion, the prefix is 0, for
* \%x and \%X prefixes are 0x and 0X and for conversion \%b the
* prefix is 0b.
* - "#" Force to print prefix. For \%o conversion, the prefix is 0, for
* \%x and \%X prefixes are 0x and 0X and for conversion \%b the
* prefix is 0b.
*
* - "-" Align to left.
* - "-" Align to left.
*
* - "+" Print positive sign just as negative.
* - "+" Print positive sign just as negative.
*
* - " " If the printed number is positive and "+" flag is not set,
* print space in place of sign.
* - " " If the printed number is positive and "+" flag is not set,
* print space in place of sign.
*
* - "0" Print 0 as padding instead of spaces. Zeroes are placed between
* sign and the rest of the number. This flag is ignored if "-"
* flag is specified.
*
* - "0" Print 0 as padding instead of spaces. Zeroes are placed between
* sign and the rest of the number. This flag is ignored if "-"
* flag is specified.
*
* WIDTH:@n
* - Specify the minimal width of a printed argument. If it is bigger,
* width is ignored. If width is specified with a "*" character instead of
* number, width is taken from parameter list. And integer parameter is
* expected before parameter for processed conversion specification. If
* this value is negative its absolute value is taken and the "-" flag is
* set.
* - Specify the minimal width of a printed argument. If it is bigger,
* width is ignored. If width is specified with a "*" character instead of
* number, width is taken from parameter list. And integer parameter is
* expected before parameter for processed conversion specification. If
* this value is negative its absolute value is taken and the "-" flag is
* set.
*
* PRECISION:@n
* - Value precision. For numbers it specifies minimum valid numbers.
* Smaller numbers are printed with leading zeroes. Bigger numbers are not
* affected. Strings with more than precision characters are cut off. Just
* as with width, an "*" can be used used instead of a number. An integer
* value is then expected in parameters. When both width and precision are
* specified using "*", the first parameter is used for width and the
* second one for precision.
*
* - Value precision. For numbers it specifies minimum valid numbers.
* Smaller numbers are printed with leading zeroes. Bigger numbers are not
* affected. Strings with more than precision characters are cut off. Just
* as with width, an "*" can be used used instead of a number. An integer
* value is then expected in parameters. When both width and precision are
* specified using "*", the first parameter is used for width and the
* second one for precision.
*
* TYPE:@n
* - "hh" Signed or unsigned char.@n
* - "h" Signed or unsigned short.@n
* - "" Signed or unsigned int (default value).@n
* - "l" Signed or unsigned long int.@n
* - "ll" Signed or unsigned long long int.@n
*
*
* - "hh" Signed or unsigned char.@n
* - "h" Signed or unsigned short.@n
* - "" Signed or unsigned int (default value).@n
* - "l" Signed or unsigned long int.@n
* If conversion is "c", the character is wchar_t (wide character).@n
* If conversion is "s", the string is wchar_t * (wide string).@n
* - "ll" Signed or unsigned long long int.@n
*
* CONVERSION:@n
* - % Print percentile character itself.
* - % Print percentile character itself.
*
* - c Print single character.
* - c Print single character. The character is expected to be plain
* ASCII (e.g. only values 0 .. 127 are valid).@n
* If type is "l", then the character is expected to be wide character
* (e.g. values 0 .. 0x10ffff are valid).
*
* - s Print zero terminated string. If a NULL value is passed as
* value, "(NULL)" is printed instead.
*
* - P, p Print value of a pointer. Void * value is expected and it is
* printed in hexadecimal notation with prefix (as with \%#X / \%#x
* for 32-bit or \%#X / \%#x for 64-bit long pointers).
* - s Print zero terminated string. If a NULL value is passed as
* value, "(NULL)" is printed instead.@n
* If type is "l", then the string is expected to be wide string.
*
* - b Print value as unsigned binary number. Prefix is not printed by
* default. (Nonstandard extension.)
*
* - o Print value as unsigned octal number. Prefix is not printed by
* default.
* - P, p Print value of a pointer. Void * value is expected and it is
* printed in hexadecimal notation with prefix (as with \%#X / \%#x
* for 32-bit or \%#X / \%#x for 64-bit long pointers).
*
* - d, i Print signed decimal number. There is no difference between d
* and i conversion.
* - b Print value as unsigned binary number. Prefix is not printed by
* default. (Nonstandard extension.)
*
* - u Print unsigned decimal number.
* - o Print value as unsigned octal number. Prefix is not printed by
* default.
*
* - X, x Print hexadecimal number with upper- or lower-case. Prefix is
* not printed by default.
*
* All other characters from fmt except the formatting directives are printed in
* - d, i Print signed decimal number. There is no difference between d
* and i conversion.
*
* - u Print unsigned decimal number.
*
* - X, x Print hexadecimal number with upper- or lower-case. Prefix is
* not printed by default.
*
* All other characters from fmt except the formatting directives are printed
* verbatim.
*
* @param fmt Formatting NULL terminated string.
* @return Number of characters printed, negative value on failure.
* @param fmt Format NULL-terminated string.
*
* @return Number of characters printed, negative value on failure.
*
*/
int printf_core(const char *fmt, struct printf_spec *ps, va_list ap)
int printf_core(const char *fmt, printf_spec_t *ps, va_list ap)
{
int i = 0; /* index of the currently processed char from fmt */
int j = 0; /* index to the first not printed nonformating character */
int end;
int counter; /* counter of printed characters */
int retval; /* used to store return values from called functions */
char c;
qualifier_t qualifier; /* type of argument */
int base; /* base in which a numeric parameter will be printed */
uint64_t number; /* argument value */
size_t size; /* byte size of integer parameter */
int width, precision;
uint64_t flags;
size_t i; /* Index of the currently processed character from fmt */
size_t nxt = 0; /* Index of the next character from fmt */
size_t j = 0; /* Index to the first not printed nonformating character */
counter = 0;
size_t counter = 0; /* Number of characters printed */
int retval; /* Return values from nested functions */
while (true) {
i = nxt;
wchar_t uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
while ((c = fmt[i])) {
/* control character */
if (c == '%') {
/* print common characters if any processed */
if (uc == 0)
break;
/* Control character */
if (uc == '%') {
/* Print common characters if any processed */
if (i > j) {
if ((retval = printf_putnchars(&fmt[j],
(size_t)(i - j), ps)) < 0) { /* error */
if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) {
/* Error */
counter = -counter;
goto out;
}
counter += retval;
}
j = i;
/* parse modifiers */
flags = 0;
end = 0;
/* Parse modifiers */
uint32_t flags = 0;
bool end = false;
do {
++i;
switch (c = fmt[i]) {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
switch (uc) {
case '#':
flags |= __PRINTF_FLAG_PREFIX;
break;
519,116 → 641,145
flags |= __PRINTF_FLAG_ZEROPADDED;
break;
default:
end = 1;
};
} while (end == 0);
end = true;
};
} while (!end);
/* width & '*' operator */
width = 0;
if (isdigit(fmt[i])) {
while (isdigit(fmt[i])) {
/* Width & '*' operator */
int width = 0;
if (isdigit(uc)) {
while (true) {
width *= 10;
width += fmt[i++] - '0';
width += uc - '0';
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 0)
break;
if (!isdigit(uc))
break;
}
} else if (fmt[i] == '*') {
/* get width value from argument list */
i++;
} else if (uc == '*') {
/* Get width value from argument list */
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
width = (int) va_arg(ap, int);
if (width < 0) {
/* negative width sets '-' flag */
/* Negative width sets '-' flag */
width *= -1;
flags |= __PRINTF_FLAG_LEFTALIGNED;
}
}
/* precision and '*' operator */
precision = 0;
if (fmt[i] == '.') {
++i;
if (isdigit(fmt[i])) {
while (isdigit(fmt[i])) {
/* Precision and '*' operator */
int precision = 0;
if (uc == '.') {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (isdigit(uc)) {
while (true) {
precision *= 10;
precision += fmt[i++] - '0';
precision += uc - '0';
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 0)
break;
if (!isdigit(uc))
break;
}
} else if (fmt[i] == '*') {
/*
* Get precision value from the argument
* list.
*/
i++;
} else if (uc == '*') {
/* Get precision value from the argument list */
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
precision = (int) va_arg(ap, int);
if (precision < 0) {
/* ignore negative precision */
/* Ignore negative precision */
precision = 0;
}
}
}
 
switch (fmt[i++]) {
/** @todo unimplemented qualifiers:
* t ptrdiff_t - ISO C 99
qualifier_t qualifier;
switch (uc) {
/** @todo Unimplemented qualifiers:
* t ptrdiff_t - ISO C 99
*/
case 'h': /* char or short */
case 'h':
/* Char or short */
qualifier = PrintfQualifierShort;
if (fmt[i] == 'h') {
i++;
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 'h') {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
qualifier = PrintfQualifierByte;
}
break;
case 'l': /* long or long long*/
case 'l':
/* Long or long long */
qualifier = PrintfQualifierLong;
if (fmt[i] == 'l') {
i++;
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
if (uc == 'l') {
i = nxt;
uc = str_decode(fmt, &nxt, STR_NO_LIMIT);
qualifier = PrintfQualifierLongLong;
}
break;
default:
/* default type */
qualifier = PrintfQualifierInt;
--i;
}
/* Default type */
qualifier = PrintfQualifierInt;
}
base = 10;
 
switch (c = fmt[i]) {
 
unsigned int base = 10;
switch (uc) {
/*
* String and character conversions.
*/
* String and character conversions.
*/
case 's':
if ((retval = print_string(va_arg(ap, char *),
width, precision, flags, ps)) < 0) {
if (qualifier == PrintfQualifierLong)
retval = print_wstr(va_arg(ap, wchar_t *), width, precision, flags, ps);
else
retval = print_str(va_arg(ap, char *), width, precision, flags, ps);
if (retval < 0) {
counter = -counter;
goto out;
};
 
}
counter += retval;
j = i + 1;
j = nxt;
goto next_char;
case 'c':
c = va_arg(ap, unsigned int);
retval = print_char(c, width, flags, ps);
if (qualifier == PrintfQualifierLong)
retval = print_wchar(va_arg(ap, wchar_t), width, flags, ps);
else
retval = print_char(va_arg(ap, unsigned int), width, flags, ps);
if (retval < 0) {
counter = -counter;
goto out;
};
counter += retval;
j = i + 1;
j = nxt;
goto next_char;
 
/*
/*
* Integer values
*/
case 'P': /* pointer */
case 'P':
/* Pointer */
flags |= __PRINTF_FLAG_BIGCHARS;
case 'p':
flags |= __PRINTF_FLAG_PREFIX;
base = 16;
qualifier = PrintfQualifierPointer;
break;
case 'b':
break;
case 'b':
base = 2;
break;
case 'o':
636,7 → 787,7
break;
case 'd':
case 'i':
flags |= __PRINTF_FLAG_SIGNED;
flags |= __PRINTF_FLAG_SIGNED;
case 'u':
break;
case 'X':
644,10 → 795,12
case 'x':
base = 16;
break;
/* percentile itself */
case '%':
/* Percentile itself */
case '%':
j = i;
goto next_char;
/*
* Bad formatting.
*/
656,12 → 809,12
* Unknown format. Now, j is the index of '%'
* so we will print whole bad format sequence.
*/
goto next_char;
goto next_char;
}
/* Print integers */
/* print number */
/* Print integers */
size_t size;
uint64_t number;
switch (qualifier) {
case PrintfQualifierByte:
size = sizeof(unsigned char);
687,7 → 840,8
size = sizeof(void *);
number = (uint64_t) (unsigned long) va_arg(ap, void *);
break;
default: /* Unknown qualifier */
default:
/* Unknown qualifier */
counter = -counter;
goto out;
}
695,7 → 849,7
if (flags & __PRINTF_FLAG_SIGNED) {
if (number & (0x1 << (size * 8 - 1))) {
flags |= __PRINTF_FLAG_NEGATIVE;
if (size == sizeof(uint64_t)) {
number = -((int64_t) number);
} else {
707,33 → 861,31
}
}
}
 
if ((retval = print_number(number, width, precision,
base, flags, ps)) < 0) {
counter = -counter;
goto out;
}
 
counter += retval;
j = i + 1;
}
j = nxt;
}
next_char:
++i;
;
}
if (i > j) {
if ((retval = printf_putnchars(&fmt[j], (unative_t) (i - j),
ps)) < 0) { /* error */
if ((retval = printf_putnchars(&fmt[j], i - j, ps)) < 0) {
/* Error */
counter = -counter;
goto out;
}
counter += retval;
}
 
out:
return counter;
return ((int) counter);
}
 
/** @}
/branches/arm/kernel/generic/src/printf/vprintf.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
39,36 → 39,66
#include <arch/asm.h>
#include <arch/types.h>
#include <typedefs.h>
#include <string.h>
 
SPINLOCK_INITIALIZE(printf_lock); /**< vprintf spinlock */
SPINLOCK_INITIALIZE(printf_lock); /**< vprintf spinlock */
 
static int vprintf_write(const char *str, size_t count, void *unused)
static int vprintf_str_write(const char *str, size_t size, void *data)
{
size_t i;
for (i = 0; i < count; i++)
putchar(str[i]);
return i;
size_t offset = 0;
size_t chars = 0;
while (offset < size) {
putchar(str_decode(str, &offset, size));
chars++;
}
return chars;
}
 
int puts(const char *s)
static int vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
{
size_t i;
for (i = 0; s[i] != 0; i++)
putchar(s[i]);
return i;
size_t offset = 0;
size_t chars = 0;
while (offset < size) {
putchar(str[chars]);
chars++;
offset += sizeof(wchar_t);
}
return chars;
}
 
int puts(const char *str)
{
size_t offset = 0;
size_t chars = 0;
wchar_t uc;
while ((uc = str_decode(str, &offset, STR_NO_LIMIT)) != 0) {
putchar(uc);
chars++;
}
return chars;
}
 
int vprintf(const char *fmt, va_list ap)
{
struct printf_spec ps = {(int(*)(void *, size_t, void *)) vprintf_write, NULL};
printf_spec_t ps = {
vprintf_str_write,
vprintf_wstr_write,
NULL
};
int irqpri = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&printf_lock);
int ret = printf_core(fmt, &ps, ap);
spinlock_unlock(&printf_lock);
interrupts_restore(irqpri);
interrupts_restore(ipl);
return ret;
}
/branches/arm/kernel/generic/src/printf/vsnprintf.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
34,62 → 34,146
 
#include <print.h>
#include <printf/printf_core.h>
#include <string.h>
#include <memstr.h>
#include <errno.h>
 
struct vsnprintf_data {
size_t size; /* total space for string */
size_t len; /* count of currently used characters */
char *string; /* destination string */
};
typedef struct {
size_t size; /* Total size of the buffer (in bytes) */
size_t len; /* Number of already used bytes */
char *dst; /* Destination */
} vsnprintf_data_t;
 
/** Write string to given buffer.
* Write at most data->size characters including trailing zero. According to C99, snprintf() has to return number
* of characters that would have been written if enough space had been available. Hence the return value is not
* number of really printed characters but size of the input string. Number of really used characters
* is stored in data->len.
* @param str source string to print
* @param count size of source string
* @param data structure with destination string, counter of used space and total string size.
* @return number of characters to print (not characters really printed!)
*
* Write at most data->size plain characters including trailing zero.
* According to C99, snprintf() has to return number of characters that
* would have been written if enough space had been available. Hence
* the return value is not the number of actually printed characters
* but size of the input string.
*
* @param str Source string to print.
* @param size Number of plain characters in str.
* @param data Structure describing destination string, counter
* of used space and total string size.
*
* @return Number of characters to print (not characters actually
* printed).
*
*/
static int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data)
static int vsnprintf_str_write(const char *str, size_t size, vsnprintf_data_t *data)
{
size_t i;
i = data->size - data->len;
 
if (i == 0) {
return count;
}
size_t left = data->size - data->len;
if (i == 1) {
/* We have only one free byte left in buffer => write there trailing zero */
data->string[data->size - 1] = 0;
if (left == 0)
return ((int) size);
if (left == 1) {
/* We have only one free byte left in buffer
* -> store trailing zero
*/
data->dst[data->size - 1] = 0;
data->len = data->size;
return count;
return ((int) size);
}
if (i <= count) {
/* We have not enought space for whole string with the trailing zero => print only a part of string */
memcpy((void *)(data->string + data->len), (void *)str, i - 1);
data->string[data->size - 1] = 0;
if (left <= size) {
/* We do not have enough space for the whole string
* with the trailing zero => print only a part
* of string
*/
size_t index = 0;
while (index < size) {
wchar_t uc = str_decode(str, &index, size);
if (chr_encode(uc, data->dst, &data->len, data->size - 1) != EOK)
break;
}
/* Put trailing zero at end, but not count it
* into data->len so it could be rewritten next time
*/
data->dst[data->len] = 0;
return ((int) size);
}
/* Buffer is big enought to print the whole string */
memcpy((void *)(data->dst + data->len), (void *) str, size);
data->len += size;
/* Put trailing zero at end, but not count it
* into data->len so it could be rewritten next time
*/
data->dst[data->len] = 0;
return ((int) size);
}
 
/** Write wide string to given buffer.
*
* Write at most data->size plain characters including trailing zero.
* According to C99, snprintf() has to return number of characters that
* would have been written if enough space had been available. Hence
* the return value is not the number of actually printed characters
* but size of the input string.
*
* @param str Source wide string to print.
* @param size Number of bytes in str.
* @param data Structure describing destination string, counter
* of used space and total string size.
*
* @return Number of wide characters to print (not characters actually
* printed).
*
*/
static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
{
size_t index = 0;
while (index < (size / sizeof(wchar_t))) {
size_t left = data->size - data->len;
if (left == 0)
return ((int) size);
if (left == 1) {
/* We have only one free byte left in buffer
* -> store trailing zero
*/
data->dst[data->size - 1] = 0;
data->len = data->size;
return count;
return ((int) size);
}
if (chr_encode(str[index], data->dst, &data->len, data->size - 1) != EOK)
break;
index++;
}
/* Buffer is big enought to print whole string */
memcpy((void *)(data->string + data->len), (void *)str, count);
data->len += count;
/* Put trailing zero at end, but not count it into data->len so it could be rewritten next time */
data->string[data->len] = 0;
 
return count;
/* Put trailing zero at end, but not count it
* into data->len so it could be rewritten next time
*/
data->dst[data->len] = 0;
return ((int) size);
}
 
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap)
{
struct vsnprintf_data data = {size, 0, str};
struct printf_spec ps = {(int(*)(void *, size_t, void *))vsnprintf_write, &data};
 
vsnprintf_data_t data = {
size,
0,
str
};
printf_spec_t ps = {
(int(*) (const char *, size_t, void *)) vsnprintf_str_write,
(int(*) (const wchar_t *, size_t, void *)) vsnprintf_wstr_write,
&data
};
/* Print 0 at end of string - fix the case that nothing will be printed */
if (size > 0)
str[0] = 0;
/branches/arm/kernel/generic/src/printf/printf.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
33,19 → 33,18
*/
 
#include <print.h>
int printf(const char *fmt, ...);
 
int printf(const char *fmt, ...)
{
int ret;
va_list args;
 
va_start(args, fmt);
 
ret = vprintf(fmt, args);
va_end(args);
 
return ret;
}
 
/branches/arm/kernel/generic/src/printf/snprintf.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup generic
/** @addtogroup generic
* @{
*/
/** @file
42,9 → 42,9
va_start(args, fmt);
ret = vsnprintf(str, size, fmt, args);
 
va_end(args);
 
return ret;
}
 
/branches/arm/kernel/generic/src/synch/spinlock.c
32,9 → 32,9
 
/**
* @file
* @brief Spinlocks.
* @brief Spinlocks.
*/
 
#include <synch/spinlock.h>
#include <atomic.h>
#include <arch/barrier.h>
75,8 → 75,7
#ifdef CONFIG_DEBUG_SPINLOCK
void spinlock_lock_debug(spinlock_t *sl)
{
count_t i = 0;
char *symbol;
size_t i = 0;
bool deadlock_reported = false;
 
preemption_disable();
106,12 → 105,10
continue;
#endif
if (i++ > DEADLOCK_THRESHOLD) {
printf("cpu%u: looping on spinlock %" PRIp ":%s, caller=%" PRIp,
CPU->id, sl, sl->name, CALLER);
symbol = get_symtab_entry(CALLER);
if (symbol)
printf("(%s)", symbol);
printf("\n");
printf("cpu%u: looping on spinlock %" PRIp ":%s, "
"caller=%" PRIp "(%s)\n", CPU->id, sl, sl->name,
CALLER, symtab_fmt_name_lookup(CALLER));
i = 0;
deadlock_reported = true;
}
/branches/arm/kernel/generic/src/synch/waitq.c
415,7 → 415,7
void _waitq_wakeup_unsafe(waitq_t *wq, wakeup_mode_t mode)
{
thread_t *t;
count_t count = 0;
size_t count = 0;
 
loop:
if (list_empty(&wq->head)) {
/branches/arm/kernel/generic/src/synch/futex.c
59,8 → 59,8
static void futex_initialize(futex_t *futex);
 
static futex_t *futex_find(uintptr_t paddr);
static index_t futex_ht_hash(unative_t *key);
static bool futex_ht_compare(unative_t *key, count_t keys, link_t *item);
static size_t futex_ht_hash(unative_t *key);
static bool futex_ht_compare(unative_t *key, size_t keys, link_t *item);
static void futex_ht_remove_callback(link_t *item);
 
/**
115,6 → 115,7
uintptr_t paddr;
pte_t *t;
ipl_t ipl;
int rc;
ipl = interrupts_disable();
 
134,9 → 135,17
interrupts_restore(ipl);
 
futex = futex_find(paddr);
return (unative_t) waitq_sleep_timeout(&futex->wq, usec, flags |
 
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
rc = waitq_sleep_timeout(&futex->wq, usec, flags |
SYNCH_FLAGS_INTERRUPTIBLE);
 
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
return (unative_t) rc;
}
 
/** Wakeup one thread waiting in futex wait queue.
279,9 → 288,9
*
* @return Index into futex hash table.
*/
index_t futex_ht_hash(unative_t *key)
size_t futex_ht_hash(unative_t *key)
{
return *key & (FUTEX_HT_SIZE-1);
return (*key & (FUTEX_HT_SIZE - 1));
}
 
/** Compare futex hash table item with a key.
291,7 → 300,7
*
* @return True if the item matches the key. False otherwise.
*/
bool futex_ht_compare(unative_t *key, count_t keys, link_t *item)
bool futex_ht_compare(unative_t *key, size_t keys, link_t *item)
{
futex_t *futex;
 
/branches/arm/kernel/generic/src/synch/rwlock.c
231,10 → 231,10
interrupts_restore(ipl);
break;
case ESYNCH_OK_ATOMIC:
panic("_mutex_lock_timeout() == ESYNCH_OK_ATOMIC\n");
panic("_mutex_lock_timeout() == ESYNCH_OK_ATOMIC.");
break;
default:
panic("invalid ESYNCH\n");
panic("Invalid ESYNCH.");
break;
}
return rc;
/branches/arm/kernel/generic/src/debug/symtab.c
32,171 → 32,222
 
/**
* @file
* @brief Kernel symbol resolver.
* @brief Kernel symbol resolver.
*/
 
#include <symtab.h>
#include <byteorder.h>
#include <func.h>
#include <string.h>
#include <print.h>
#include <arch/types.h>
#include <typedefs.h>
#include <errno.h>
 
/** Return entry that seems most likely to correspond to argument.
/** Get name of a symbol that seems most likely to correspond to address.
*
* Return entry that seems most likely to correspond
* to address passed in the argument.
*
* @param addr Address.
* @param name Place to store pointer to the symbol name.
*
* @return Pointer to respective symbol string on success, NULL otherwise.
* @return Zero on success or negative error code, ENOENT if not found,
* ENOTSUP if symbol table not available.
*
*/
char * get_symtab_entry(unative_t addr)
int symtab_name_lookup(unative_t addr, char **name)
{
count_t i;
 
for (i = 1; symbol_table[i].address_le; ++i) {
#ifdef CONFIG_SYMTAB
size_t i;
for (i = 1; symbol_table[i].address_le; i++) {
if (addr < uint64_t_le2host(symbol_table[i].address_le))
break;
}
if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le))
return symbol_table[i - 1].symbol_name;
return NULL;
if (addr >= uint64_t_le2host(symbol_table[i - 1].address_le)) {
*name = symbol_table[i - 1].symbol_name;
return EOK;
}
*name = NULL;
return ENOENT;
#else
*name = NULL;
return ENOTSUP;
#endif
}
 
/** Find symbols that match the parameter forward and print them.
/** Lookup symbol by address and format for display.
*
* @param name - search string
* @param startpos - starting position, changes to found position
* @return Pointer to the part of string that should be completed or NULL
* Returns name of closest corresponding symbol, "Not found" if none exists
* or "N/A" if no symbol information is available.
*
* @param addr Address.
* @param name Place to store pointer to the symbol name.
*
* @return Pointer to a human-readable string.
*
*/
static char * symtab_search_one(const char *name, int *startpos)
char *symtab_fmt_name_lookup(unative_t addr)
{
unsigned int namelen = strlen(name);
char *curname;
int i, j;
int colonoffset = -1;
char *name;
int rc = symtab_name_lookup(addr, &name);
switch (rc) {
case EOK:
return name;
case ENOENT:
return "Not found";
default:
return "N/A";
}
}
 
for (i = 0; name[i]; i++)
if (name[i] == ':') {
colonoffset = i;
break;
}
#ifdef CONFIG_SYMTAB
 
for (i = *startpos; symbol_table[i].address_le; ++i) {
/* Find a ':' in name */
curname = symbol_table[i].symbol_name;
for (j = 0; curname[j] && curname[j] != ':'; j++)
;
if (!curname[j])
/** Find symbols that match the parameter forward and print them.
*
* @param name Search string
* @param startpos Starting position, changes to found position
*
* @return Pointer to the part of string that should be completed or NULL.
*
*/
static const char *symtab_search_one(const char *name, size_t *startpos)
{
size_t namelen = str_length(name);
size_t pos;
for (pos = *startpos; symbol_table[pos].address_le; pos++) {
const char *curname = symbol_table[pos].symbol_name;
/* Find a ':' in curname */
const char *colon = str_chr(curname, ':');
if (colon == NULL)
continue;
j -= colonoffset;
curname += j;
if (strlen(curname) < namelen)
if (str_length(curname) < namelen)
continue;
if (strncmp(curname, name, namelen) == 0) {
*startpos = i;
return curname + namelen;
if (str_lcmp(name, curname, namelen) == 0) {
*startpos = pos;
return (curname + str_lsize(curname, namelen));
}
}
return NULL;
}
 
/** Return address that corresponds to the entry
#endif
 
/** Return address that corresponds to the entry.
*
* Search symbol table, and if there is one match, return it
*
* @param name Name of the symbol
* @return 0 - Not found, -1 - Duplicate symbol, other - address of symbol
* @param addr Place to store symbol address
*
* @return Zero on success, ENOENT - not found, EOVERFLOW - duplicate
* symbol, ENOTSUP - no symbol information available.
*
*/
uintptr_t get_symbol_addr(const char *name)
int symtab_addr_lookup(const char *name, uintptr_t *addr)
{
count_t found = 0;
uintptr_t addr = NULL;
char *hint;
int i;
 
i = 0;
while ((hint = symtab_search_one(name, &i))) {
if (!strlen(hint)) {
addr = uint64_t_le2host(symbol_table[i].address_le);
#ifdef CONFIG_SYMTAB
size_t found = 0;
size_t pos = 0;
const char *hint;
while ((hint = symtab_search_one(name, &pos))) {
if (str_length(hint) == 0) {
*addr = uint64_t_le2host(symbol_table[pos].address_le);
found++;
}
i++;
pos++;
}
if (found > 1)
return ((uintptr_t) -1);
return addr;
return EOVERFLOW;
if (found < 1)
return ENOENT;
return EOK;
#else
return ENOTSUP;
#endif
}
 
/** Find symbols that match parameter and prints them */
/** Find symbols that match parameter and print them */
void symtab_print_search(const char *name)
{
int i;
uintptr_t addr;
char *realname;
 
 
i = 0;
while (symtab_search_one(name, &i)) {
addr = uint64_t_le2host(symbol_table[i].address_le);
realname = symbol_table[i].symbol_name;
#ifdef CONFIG_SYMTAB
size_t pos = 0;
while (symtab_search_one(name, &pos)) {
uintptr_t addr = uint64_t_le2host(symbol_table[pos].address_le);
char *realname = symbol_table[pos].symbol_name;
printf("%p: %s\n", addr, realname);
i++;
pos++;
}
#else
printf("No symbol information available.\n");
#endif
}
 
/** Symtab completion
*
* @param input - Search string, completes to symbol name
* @returns - 0 - nothing found, 1 - success, >1 print duplicates
* @param input Search string, completes to symbol name
* @param size Input buffer size
*
* @return 0 - nothing found, 1 - success, >1 print duplicates
*
*/
int symtab_compl(char *input)
int symtab_compl(char *input, size_t size)
{
char output[MAX_SYMBOL_NAME + 1];
int startpos = 0;
char *foundtxt;
int found = 0;
int i;
char *name = input;
 
/* Allow completion of pointers */
if (name[0] == '*' || name[0] == '&')
#ifdef CONFIG_SYMTAB
const char *name = input;
/* Allow completion of pointers */
if ((name[0] == '*') || (name[0] == '&'))
name++;
 
/* Do not print everything */
if (!strlen(name))
/* Do not print all symbols */
if (str_length(name) == 0)
return 0;
 
output[0] = '\0';
 
while ((foundtxt = symtab_search_one(name, &startpos))) {
startpos++;
if (!found)
strncpy(output, foundtxt, strlen(foundtxt) + 1);
else {
for (i = 0; output[i] && foundtxt[i] &&
output[i] == foundtxt[i]; i++)
;
output[i] = '\0';
}
size_t found = 0;
size_t pos = 0;
const char *hint;
char output[MAX_SYMBOL_NAME];
output[0] = 0;
while ((hint = symtab_search_one(name, &pos))) {
if ((found == 0) || (str_length(output) > str_length(hint)))
str_cpy(output, MAX_SYMBOL_NAME, hint);
pos++;
found++;
}
if (!found)
return 0;
 
if (found > 1 && !strlen(output)) {
if ((found > 1) && (str_length(output) != 0)) {
printf("\n");
startpos = 0;
while ((foundtxt = symtab_search_one(name, &startpos))) {
printf("%s\n", symbol_table[startpos].symbol_name);
startpos++;
pos = 0;
while ((hint = symtab_search_one(name, &pos))) {
printf("%s\n", symbol_table[pos].symbol_name);
pos++;
}
}
strncpy(input, output, MAX_SYMBOL_NAME);
if (found > 0)
str_cpy(input, size, output);
return found;
#else
return 0;
#endif
}
 
/** @}
/branches/arm/kernel/generic/src/time/clock.c
79,7 → 79,7
 
faddr = frame_alloc(ONE_FRAME, FRAME_ATOMIC);
if (!faddr)
panic("Cannot allocate page for clock");
panic("Cannot allocate page for clock.");
uptime = (uptime_t *) PA2KA(faddr);
88,9 → 88,7
uptime->useconds = 0;
 
clock_parea.pbase = (uintptr_t) faddr;
clock_parea.vbase = (uintptr_t) uptime;
clock_parea.frames = 1;
clock_parea.cacheable = true;
ddi_parea_register(&clock_parea);
 
/*
136,7 → 134,7
timeout_t *h;
timeout_handler_t f;
void *arg;
count_t missed_clock_ticks = CPU->missed_clock_ticks;
size_t missed_clock_ticks = CPU->missed_clock_ticks;
unsigned int i;
 
/*
189,7 → 187,19
spinlock_unlock(&THREAD->lock);
if (!ticks && !PREEMPTION_DISABLED) {
#ifdef CONFIG_UDEBUG
istate_t *istate;
#endif
scheduler();
#ifdef CONFIG_UDEBUG
/*
* Give udebug chance to stop the thread
* before it begins executing userspace code.
*/
istate = THREAD->udebug.uspace_state;
if (istate && istate_from_uspace(istate))
udebug_before_thread_runs();
#endif
}
}
 
/branches/arm/kernel/generic/src/time/timeout.c
113,7 → 113,7
spinlock_lock(&t->lock);
 
if (t->cpu)
panic("t->cpu != 0");
panic("Unexpected: t->cpu != 0.");
 
t->cpu = CPU;
t->ticks = us2ticks(time);
/branches/arm/kernel/generic/src/ddi/ddi.c
29,10 → 29,10
/** @addtogroup genericddi
* @{
*/
 
/**
* @file
* @brief Device Driver Interface functions.
* @brief Device Driver Interface functions.
*
* This file contains functions that comprise the Device Driver Interface.
* These are the functions for mapping physical memory and enabling I/O
68,82 → 68,100
*
* @param parea Pointer to physical area structure.
*
* @todo This function doesn't check for overlaps. It depends on the kernel to
* create disjunct physical memory areas.
*/
void ddi_parea_register(parea_t *parea)
{
ipl_t ipl;
 
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&parea_lock);
/*
* TODO: we should really check for overlaps here.
* However, we should be safe because the kernel is pretty sane and
* memory of different devices doesn't overlap.
* We don't check for overlaps here as the kernel is pretty sane.
*/
btree_insert(&parea_btree, (btree_key_t) parea->pbase, parea, NULL);
 
spinlock_unlock(&parea_lock);
interrupts_restore(ipl);
interrupts_restore(ipl);
}
 
/** Map piece of physical memory into virtual address space of current task.
*
* @param pf Physical address of the starting frame.
* @param vp Virtual address of the starting page.
* @param pf Physical address of the starting frame.
* @param vp Virtual address of the starting page.
* @param pages Number of pages to map.
* @param flags Address space area flags for the mapping.
*
* @return 0 on success, EPERM if the caller lacks capabilities to use this
* syscall, ENOENT if there is no task matching the specified ID or the
* physical address space is not enabled for mapping and ENOMEM if there
* was a problem in creating address space area.
* syscall, EBADMEM if pf or vf is not page aligned, ENOENT if there
* is no task matching the specified ID or the physical address space
* is not enabled for mapping and ENOMEM if there was a problem in
* creating address space area.
*
*/
static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, count_t pages, int flags)
static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, size_t pages, int flags)
{
ipl_t ipl;
cap_t caps;
mem_backend_data_t backend_data;
 
backend_data.base = pf;
backend_data.frames = pages;
ASSERT(TASK);
ASSERT((pf % FRAME_SIZE) == 0);
ASSERT((vp % PAGE_SIZE) == 0);
/*
* Make sure the caller is authorised to make this syscall.
*/
caps = cap_get(TASK);
cap_t caps = cap_get(TASK);
if (!(caps & CAP_MEM_MANAGER))
return EPERM;
 
ipl = interrupts_disable();
 
/*
* Check if the physical memory area is enabled for mapping.
* If the architecture supports virtually indexed caches, intercept
* attempts to create an illegal address alias.
*/
spinlock_lock(&parea_lock);
parea_t *parea;
btree_node_t *nodep;
parea = (parea_t *) btree_search(&parea_btree, (btree_key_t) pf, &nodep);
if (!parea || parea->frames < pages || ((flags & AS_AREA_CACHEABLE) &&
!parea->cacheable) || (!(flags & AS_AREA_CACHEABLE) &&
parea->cacheable)) {
/*
* This physical memory area cannot be mapped.
mem_backend_data_t backend_data;
backend_data.base = pf;
backend_data.frames = pages;
ipl_t ipl = interrupts_disable();
/* Find the zone of the physical memory */
spinlock_lock(&zones.lock);
size_t znum = find_zone(ADDR2PFN(pf), pages, 0);
if (znum == (size_t) -1) {
/* Frames not found in any zones
* -> assume it is hardware device and allow mapping
*/
spinlock_unlock(&zones.lock);
goto map;
}
if (zones.info[znum].flags & ZONE_FIRMWARE) {
/* Frames are part of firmware */
spinlock_unlock(&zones.lock);
goto map;
}
if (zone_flags_available(zones.info[znum].flags)) {
/* Frames are part of physical memory, check if the memory
* region is enabled for mapping.
*/
spinlock_unlock(&zones.lock);
spinlock_lock(&parea_lock);
btree_node_t *nodep;
parea_t *parea = (parea_t *) btree_search(&parea_btree,
(btree_key_t) pf, &nodep);
if ((!parea) || (parea->frames < pages))
goto err;
spinlock_unlock(&parea_lock);
interrupts_restore(ipl);
return ENOENT;
goto map;
}
spinlock_unlock(&parea_lock);
 
err:
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return ENOENT;
map:
spinlock_lock(&TASK->lock);
if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE,
&phys_backend, &backend_data)) {
if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp,
AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
/*
* The address space area could not have been created.
* We report it using ENOMEM.
169,28 → 187,24
* @param size Size of the enabled I/O space..
*
* @return 0 on success, EPERM if the caller lacks capabilities to use this
* syscall, ENOENT if there is no task matching the specified ID.
* syscall, ENOENT if there is no task matching the specified ID.
*
*/
static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size)
{
ipl_t ipl;
cap_t caps;
task_t *t;
int rc;
/*
* Make sure the caller is authorised to make this syscall.
*/
caps = cap_get(TASK);
cap_t caps = cap_get(TASK);
if (!(caps & CAP_IO_MANAGER))
return EPERM;
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&tasks_lock);
t = task_find_by_id(id);
task_t *task = task_find_by_id(id);
if ((!t) || (!context_check(CONTEXT, t->context))) {
if ((!task) || (!context_check(CONTEXT, task->context))) {
/*
* There is no task with the specified ID
* or the task belongs to a different security
200,15 → 214,16
interrupts_restore(ipl);
return ENOENT;
}
 
/* Lock the task and release the lock protecting tasks_btree. */
spinlock_lock(&t->lock);
spinlock_lock(&task->lock);
spinlock_unlock(&tasks_lock);
 
rc = ddi_iospace_enable_arch(t, ioaddr, size);
spinlock_unlock(&t->lock);
int rc = ddi_iospace_enable_arch(task, ioaddr, size);
spinlock_unlock(&task->lock);
interrupts_restore(ipl);
return rc;
}
 
220,13 → 235,14
* @param flags Flags of newly mapped pages
*
* @return 0 on success, otherwise it returns error code found in errno.h
*/
*
*/
unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base,
unative_t pages, unative_t flags)
{
return (unative_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base,
FRAME_SIZE), ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE),
(count_t) pages, (int) flags);
(size_t) pages, (int) flags);
}
 
/** Wrapper for SYS_ENABLE_IOSPACE syscall.
234,16 → 250,15
* @param uspace_io_arg User space address of DDI argument structure.
*
* @return 0 on success, otherwise it returns error code found in errno.h
*/
*
*/
unative_t sys_iospace_enable(ddi_ioarg_t *uspace_io_arg)
{
ddi_ioarg_t arg;
int rc;
rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
int rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
if (rc != 0)
return (unative_t) rc;
return (unative_t) ddi_iospace_enable((task_id_t) arg.task_id,
(uintptr_t) arg.ioaddr, (size_t) arg.size);
}
251,20 → 266,24
/** Disable or enable preemption.
*
* @param enable If non-zero, the preemption counter will be decremented,
* leading to potential enabling of preemption. Otherwise the preemption
* counter will be incremented, preventing preemption from occurring.
* leading to potential enabling of preemption. Otherwise
* the preemption counter will be incremented, preventing
* preemption from occurring.
*
* @return Zero on success or EPERM if callers capabilities are not sufficient.
*/
*
*/
unative_t sys_preempt_control(int enable)
{
if (!cap_get(TASK) & CAP_PREEMPT_CONTROL)
return EPERM;
if (enable)
preemption_enable();
else
preemption_disable();
return 0;
if (!cap_get(TASK) & CAP_PREEMPT_CONTROL)
return EPERM;
if (enable)
preemption_enable();
else
preemption_disable();
return 0;
}
 
/** @}
/branches/arm/kernel/generic/src/ddi/irq.c
39,7 → 39,8
*
* This code is designed to support:
* - multiple devices sharing single IRQ
* - multiple IRQs per signle device
* - multiple IRQs per single device
* - multiple instances of the same device
*
*
* Note about architectures.
68,8 → 69,11
 
#include <ddi/irq.h>
#include <adt/hash_table.h>
#include <mm/slab.h>
#include <arch/types.h>
#include <synch/spinlock.h>
#include <console/console.h>
#include <memstr.h>
#include <arch.h>
 
#define KEY_INR 0
76,23 → 80,33
#define KEY_DEVNO 1
 
/**
* Spinlock protecting the hash table.
* Spinlock protecting the kernel IRQ hash table.
* This lock must be taken only when interrupts are disabled.
*/
SPINLOCK_INITIALIZE(irq_hash_table_lock);
static hash_table_t irq_hash_table;
SPINLOCK_INITIALIZE(irq_kernel_hash_table_lock);
/** The kernel IRQ hash table. */
static hash_table_t irq_kernel_hash_table;
 
/**
* Spinlock protecting the uspace IRQ hash table.
* This lock must be taken only when interrupts are disabled.
*/
SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock);
/** The uspace IRQ hash table. */
hash_table_t irq_uspace_hash_table;
 
/**
* Hash table operations for cases when we know that
* there will be collisions between different keys.
*/
static index_t irq_ht_hash(unative_t *key);
static bool irq_ht_compare(unative_t *key, count_t keys, link_t *item);
static size_t irq_ht_hash(unative_t *key);
static bool irq_ht_compare(unative_t *key, size_t keys, link_t *item);
static void irq_ht_remove(link_t *item);
 
static hash_table_operations_t irq_ht_ops = {
.hash = irq_ht_hash,
.compare = irq_ht_compare,
.remove_callback = NULL /* not used */
.remove_callback = irq_ht_remove,
};
 
/**
101,22 → 115,27
* However, there might be still collisions among
* elements with single key (sharing of one IRQ).
*/
static index_t irq_lin_hash(unative_t *key);
static bool irq_lin_compare(unative_t *key, count_t keys, link_t *item);
static size_t irq_lin_hash(unative_t *key);
static bool irq_lin_compare(unative_t *key, size_t keys, link_t *item);
static void irq_lin_remove(link_t *item);
 
static hash_table_operations_t irq_lin_ops = {
.hash = irq_lin_hash,
.compare = irq_lin_compare,
.remove_callback = NULL /* not used */
.remove_callback = irq_lin_remove,
};
 
/** Number of buckets in either of the hash tables. */
static size_t buckets;
 
/** Initialize IRQ subsystem.
*
* @param inrs Numbers of unique IRQ numbers or INRs.
* @param chains Number of chains in the hash table.
*/
void irq_init(count_t inrs, count_t chains)
void irq_init(size_t inrs, size_t chains)
{
buckets = chains;
/*
* Be smart about the choice of the hash table operations.
* In cases in which inrs equals the requested number of
123,10 → 142,17
* chains (i.e. where there is no collision between
* different keys), we can use optimized set of operations.
*/
if (inrs == chains)
hash_table_create(&irq_hash_table, chains, 2, &irq_lin_ops);
else
hash_table_create(&irq_hash_table, chains, 2, &irq_ht_ops);
if (inrs == chains) {
hash_table_create(&irq_uspace_hash_table, chains, 2,
&irq_lin_ops);
hash_table_create(&irq_kernel_hash_table, chains, 2,
&irq_lin_ops);
} else {
hash_table_create(&irq_uspace_hash_table, chains, 2,
&irq_ht_ops);
hash_table_create(&irq_kernel_hash_table, chains, 2,
&irq_ht_ops);
}
}
 
/** Initialize one IRQ structure.
136,21 → 162,12
*/
void irq_initialize(irq_t *irq)
{
memsetb(irq, sizeof(irq_t), 0);
link_initialize(&irq->link);
spinlock_initialize(&irq->lock, "irq.lock");
irq->preack = false;
link_initialize(&irq->notif_cfg.link);
irq->inr = -1;
irq->devno = -1;
irq->trigger = (irq_trigger_t) 0;
irq->claim = NULL;
irq->handler = NULL;
irq->arg = NULL;
irq->notif_cfg.notify = false;
irq->notif_cfg.answerbox = NULL;
irq->notif_cfg.code = NULL;
irq->notif_cfg.method = 0;
irq->notif_cfg.counter = 0;
link_initialize(&irq->notif_cfg.link);
}
 
/** Register IRQ for device.
157,9 → 174,10
*
* The irq structure must be filled with information
* about the interrupt source and with the claim()
* function pointer and irq_handler() function pointer.
* function pointer and handler() function pointer.
*
* @param irq IRQ structure belonging to a device.
* @param irq IRQ structure belonging to a device.
* @return True on success, false on failure.
*/
void irq_register(irq_t *irq)
{
170,88 → 188,101
};
ipl = interrupts_disable();
spinlock_lock(&irq_hash_table_lock);
hash_table_insert(&irq_hash_table, key, &irq->link);
spinlock_unlock(&irq_hash_table_lock);
spinlock_lock(&irq_kernel_hash_table_lock);
spinlock_lock(&irq->lock);
hash_table_insert(&irq_kernel_hash_table, key, &irq->link);
spinlock_unlock(&irq->lock);
spinlock_unlock(&irq_kernel_hash_table_lock);
interrupts_restore(ipl);
}
 
/** Dispatch the IRQ.
/** Search and lock the uspace IRQ hash table.
*
* We assume this function is only called from interrupt
* context (i.e. that interrupts are disabled prior to
* this call).
*
* This function attempts to lookup a fitting IRQ
* structure. In case of success, return with interrupts
* disabled and holding the respective structure.
*
* @param inr Interrupt number (aka inr or irq).
*
* @return IRQ structure of the respective device or NULL.
*/
irq_t *irq_dispatch_and_lock(inr_t inr)
static irq_t *irq_dispatch_and_lock_uspace(inr_t inr)
{
link_t *lnk;
unative_t key[] = {
(unative_t) inr,
(unative_t) -1 /* search will use claim() instead of devno */
(unative_t) -1 /* search will use claim() instead of devno */
};
spinlock_lock(&irq_hash_table_lock);
 
lnk = hash_table_find(&irq_hash_table, key);
spinlock_lock(&irq_uspace_hash_table_lock);
lnk = hash_table_find(&irq_uspace_hash_table, key);
if (lnk) {
irq_t *irq;
irq = hash_table_get_instance(lnk, irq_t, link);
 
spinlock_unlock(&irq_hash_table_lock);
spinlock_unlock(&irq_uspace_hash_table_lock);
return irq;
}
spinlock_unlock(&irq_uspace_hash_table_lock);
spinlock_unlock(&irq_hash_table_lock);
 
return NULL;
return NULL;
}
 
/** Find the IRQ structure corresponding to inr and devno.
/** Search and lock the kernel IRQ hash table.
*
* This functions attempts to lookup the IRQ structure
* corresponding to its arguments. On success, this
* function returns with interrups disabled, holding
* the lock of the respective IRQ structure.
*
* This function assumes interrupts are already disabled.
*
* @param inr INR being looked up.
* @param devno Devno being looked up.
*
* @return Locked IRQ structure on success or NULL on failure.
*/
irq_t *irq_find_and_lock(inr_t inr, devno_t devno)
static irq_t *irq_dispatch_and_lock_kernel(inr_t inr)
{
link_t *lnk;
unative_t keys[] = {
unative_t key[] = {
(unative_t) inr,
(unative_t) devno
(unative_t) -1 /* search will use claim() instead of devno */
};
spinlock_lock(&irq_hash_table_lock);
 
lnk = hash_table_find(&irq_hash_table, keys);
spinlock_lock(&irq_kernel_hash_table_lock);
lnk = hash_table_find(&irq_kernel_hash_table, key);
if (lnk) {
irq_t *irq;
irq = hash_table_get_instance(lnk, irq_t, link);
 
spinlock_unlock(&irq_hash_table_lock);
spinlock_unlock(&irq_kernel_hash_table_lock);
return irq;
}
spinlock_unlock(&irq_kernel_hash_table_lock);
spinlock_unlock(&irq_hash_table_lock);
return NULL;
}
 
return NULL;
/** Dispatch the IRQ.
*
* We assume this function is only called from interrupt
* context (i.e. that interrupts are disabled prior to
* this call).
*
* This function attempts to lookup a fitting IRQ
* structure. In case of success, return with interrupts
* disabled and holding the respective structure.
*
* @param inr Interrupt number (aka inr or irq).
*
* @return IRQ structure of the respective device or NULL.
*/
irq_t *irq_dispatch_and_lock(inr_t inr)
{
irq_t *irq;
/*
* If the kernel console is silenced,
* then try first the uspace handlers,
* eventually fall back to kernel handlers.
*
* If the kernel console is active,
* then do it the other way around.
*/
if (silent) {
irq = irq_dispatch_and_lock_uspace(inr);
if (irq)
return irq;
return irq_dispatch_and_lock_kernel(inr);
}
irq = irq_dispatch_and_lock_kernel(inr);
if (irq)
return irq;
return irq_dispatch_and_lock_uspace(inr);
}
 
/** Compute hash index for the key.
267,10 → 298,10
*
* @return Index into the hash table.
*/
index_t irq_ht_hash(unative_t key[])
size_t irq_ht_hash(unative_t key[])
{
inr_t inr = (inr_t) key[KEY_INR];
return inr % irq_hash_table.entries;
return inr % buckets;
}
 
/** Compare hash table element with a key.
293,7 → 324,7
*
* @return True on match or false otherwise.
*/
bool irq_ht_compare(unative_t key[], count_t keys, link_t *item)
bool irq_ht_compare(unative_t key[], size_t keys, link_t *item)
{
irq_t *irq = hash_table_get_instance(item, irq_t, link);
inr_t inr = (inr_t) key[KEY_INR];
304,7 → 335,8
spinlock_lock(&irq->lock);
if (devno == -1) {
/* Invoked by irq_dispatch_and_lock(). */
rv = ((irq->inr == inr) && (irq->claim() == IRQ_ACCEPT));
rv = ((irq->inr == inr) &&
(irq->claim(irq) == IRQ_ACCEPT));
} else {
/* Invoked by irq_find_and_lock(). */
rv = ((irq->inr == inr) && (irq->devno == devno));
317,6 → 349,17
return rv;
}
 
/** Unlock IRQ structure after hash_table_remove().
*
* @param lnk Link in the removed and locked IRQ structure.
*/
void irq_ht_remove(link_t *lnk)
{
irq_t *irq __attribute__((unused))
= hash_table_get_instance(lnk, irq_t, link);
spinlock_unlock(&irq->lock);
}
 
/** Compute hash index for the key.
*
* This function computes hash index into
328,7 → 371,7
*
* @return Index into the hash table.
*/
index_t irq_lin_hash(unative_t key[])
size_t irq_lin_hash(unative_t key[])
{
inr_t inr = (inr_t) key[KEY_INR];
return inr;
354,7 → 397,7
*
* @return True on match or false otherwise.
*/
bool irq_lin_compare(unative_t key[], count_t keys, link_t *item)
bool irq_lin_compare(unative_t key[], size_t keys, link_t *item)
{
irq_t *irq = list_get_instance(item, irq_t, link);
devno_t devno = (devno_t) key[KEY_DEVNO];
363,7 → 406,7
spinlock_lock(&irq->lock);
if (devno == -1) {
/* Invoked by irq_dispatch_and_lock() */
rv = (irq->claim() == IRQ_ACCEPT);
rv = (irq->claim(irq) == IRQ_ACCEPT);
} else {
/* Invoked by irq_find_and_lock() */
rv = (irq->devno == devno);
376,5 → 419,16
return rv;
}
 
/** Unlock IRQ structure after hash_table_remove().
*
* @param lnk Link in the removed and locked IRQ structure.
*/
void irq_lin_remove(link_t *lnk)
{
irq_t *irq __attribute__((unused))
= hash_table_get_instance(lnk, irq_t, link);
spinlock_unlock(&irq->lock);
}
 
/** @}
*/
/branches/arm/kernel/generic/src/ddi/device.c
31,7 → 31,7
*/
/**
* @file
* @brief Device numbers.
* @brief Device numbers.
*/
 
#include <arch/types.h>
47,13 → 47,16
*/
devno_t device_assign_devno(void)
{
devno_t devno;
 
devno = (devno_t) atomic_postinc(&last);
devno_t devno = (devno_t) atomic_postinc(&last);
ASSERT(devno >= 0);
 
return devno;
}
 
unative_t sys_device_assign_devno(void)
{
return (unative_t) device_assign_devno();
}
 
/** @}
*/
/branches/arm/kernel/generic/src/console/console.c
39,79 → 39,70
#include <synch/waitq.h>
#include <synch/spinlock.h>
#include <arch/types.h>
#include <ddi/device.h>
#include <ddi/irq.h>
#include <ddi/ddi.h>
#include <ipc/event.h>
#include <ipc/irq.h>
#include <arch.h>
#include <func.h>
#include <print.h>
#include <putchar.h>
#include <atomic.h>
#include <syscall/copy.h>
#include <errno.h>
#include <string.h>
 
#define KLOG_SIZE PAGE_SIZE
#define KLOG_LATENCY 8
#define KLOG_PAGES 4
#define KLOG_LENGTH (KLOG_PAGES * PAGE_SIZE / sizeof(wchar_t))
#define KLOG_LATENCY 8
 
/**< Kernel log cyclic buffer */
static char klog[KLOG_SIZE] __attribute__ ((aligned (PAGE_SIZE)));
/** Kernel log cyclic buffer */
static wchar_t klog[KLOG_LENGTH] __attribute__ ((aligned (PAGE_SIZE)));
 
/**< Kernel log initialized */
/** Kernel log initialized */
static bool klog_inited = false;
/**< First kernel log characters */
static index_t klog_start = 0;
/**< Number of valid kernel log characters */
/** First kernel log characters */
static size_t klog_start = 0;
/** Number of valid kernel log characters */
static size_t klog_len = 0;
/**< Number of stored (not printed) kernel log characters */
/** Number of stored (not printed) kernel log characters */
static size_t klog_stored = 0;
/**< Number of stored kernel log characters for uspace */
/** Number of stored kernel log characters for uspace */
static size_t klog_uspace = 0;
 
/**< Kernel log spinlock */
/** Kernel log spinlock */
SPINLOCK_INITIALIZE(klog_lock);
 
/** Physical memory area used for klog buffer */
static parea_t klog_parea;
/*
* For now, we use 0 as INR.
* However, it is therefore desirable to have architecture specific
* definition of KLOG_VIRT_INR in the future.
*/
#define KLOG_VIRT_INR 0
 
static irq_t klog_irq;
 
static chardev_operations_t null_stdout_ops = {
.suspend = NULL,
.resume = NULL,
.write = NULL,
.read = NULL
static indev_operations_t stdin_ops = {
.poll = NULL
};
 
chardev_t null_stdout = {
.name = "null",
.op = &null_stdout_ops
};
/** Silence output */
bool silent = false;
 
/** Allways refuse IRQ ownership.
*
* This is not a real IRQ, so we always decline.
*
* @return Always returns IRQ_DECLINE.
*/
static irq_ownership_t klog_claim(void)
/** Standard input and output character devices */
indev_t *stdin = NULL;
outdev_t *stdout = NULL;
 
indev_t *stdin_wire(void)
{
return IRQ_DECLINE;
if (stdin == NULL) {
stdin = malloc(sizeof(indev_t), FRAME_ATOMIC);
if (stdin != NULL)
indev_initialize("stdin", stdin, &stdin_ops);
}
return stdin;
}
 
/** Standard input character device */
chardev_t *stdin = NULL;
chardev_t *stdout = &null_stdout;
 
/** Initialize kernel logging facility
*
* The shared area contains kernel cyclic buffer. Userspace application may
* be notified on new data with indication of position and size
* of the data within the circular buffer.
*
*/
void klog_init(void)
{
118,26 → 109,13
void *faddr = (void *) KA2PA(klog);
ASSERT((uintptr_t) faddr % FRAME_SIZE == 0);
ASSERT(KLOG_SIZE % FRAME_SIZE == 0);
 
devno_t devno = device_assign_devno();
klog_parea.pbase = (uintptr_t) faddr;
klog_parea.vbase = (uintptr_t) klog;
klog_parea.frames = SIZE2FRAMES(KLOG_SIZE);
klog_parea.cacheable = true;
klog_parea.frames = SIZE2FRAMES(sizeof(klog));
ddi_parea_register(&klog_parea);
 
sysinfo_set_item_val("klog.faddr", NULL, (unative_t) faddr);
sysinfo_set_item_val("klog.pages", NULL, SIZE2FRAMES(KLOG_SIZE));
sysinfo_set_item_val("klog.devno", NULL, devno);
sysinfo_set_item_val("klog.inr", NULL, KLOG_VIRT_INR);
 
irq_initialize(&klog_irq);
klog_irq.devno = devno;
klog_irq.inr = KLOG_VIRT_INR;
klog_irq.claim = klog_claim;
irq_register(&klog_irq);
sysinfo_set_item_val("klog.pages", NULL, KLOG_PAGES);
spinlock_lock(&klog_lock);
klog_inited = true;
144,91 → 122,88
spinlock_unlock(&klog_lock);
}
 
/** Get character from character device. Do not echo character.
*
* @param chardev Character device.
*
* @return Character read.
*/
uint8_t _getc(chardev_t *chardev)
void grab_console(void)
{
uint8_t ch;
ipl_t ipl;
bool prev = silent;
silent = false;
arch_grab_console();
/* Force the console to print the prompt */
if ((stdin) && (prev))
indev_push_character(stdin, '\n');
}
 
if (atomic_get(&haltstate)) {
/* If we are here, we are hopefully on the processor, that
* issued the 'halt' command, so proceed to read the character
* directly from input
*/
if (chardev->op->read)
return chardev->op->read(chardev);
/* no other way of interacting with user, halt */
if (CPU)
printf("cpu%u: ", CPU->id);
else
printf("cpu: ");
printf("halted - no kconsole\n");
cpu_halt();
}
void release_console(void)
{
silent = true;
arch_release_console();
}
 
waitq_sleep(&chardev->wq);
ipl = interrupts_disable();
spinlock_lock(&chardev->lock);
ch = chardev->buffer[(chardev->index - chardev->counter) % CHARDEV_BUFLEN];
chardev->counter--;
spinlock_unlock(&chardev->lock);
interrupts_restore(ipl);
/** Tell kernel to get keyboard/console access again */
unative_t sys_debug_enable_console(void)
{
#ifdef CONFIG_KCONSOLE
grab_console();
return true;
#else
return false;
#endif
}
 
chardev->op->resume(chardev);
 
return ch;
/** Tell kernel to relinquish keyboard/console access */
unative_t sys_debug_disable_console(void)
{
release_console();
return true;
}
 
/** Get string from character device.
/** Get string from input character device.
*
* Read characters from character device until first occurrence
* Read characters from input character device until first occurrence
* of newline character.
*
* @param chardev Character device.
* @param buf Buffer where to store string terminated by '\0'.
* @param indev Input character device.
* @param buf Buffer where to store string terminated by NULL.
* @param buflen Size of the buffer.
*
* @return Number of characters read.
*
*/
count_t gets(chardev_t *chardev, char *buf, size_t buflen)
size_t gets(indev_t *indev, char *buf, size_t buflen)
{
index_t index = 0;
char ch;
 
while (index < buflen) {
ch = _getc(chardev);
size_t offset = 0;
size_t count = 0;
buf[offset] = 0;
wchar_t ch;
while ((ch = indev_pop_character(indev)) != '\n') {
if (ch == '\b') {
if (index > 0) {
index--;
/* Space backspace, space */
if (count > 0) {
/* Space, backspace, space */
putchar('\b');
putchar(' ');
putchar('\b');
count--;
offset = str_lsize(buf, count);
buf[offset] = 0;
}
continue;
}
putchar(ch);
 
if (ch == '\n') { /* end of string => write 0, return */
buf[index] = '\0';
return (count_t) index;
}
buf[index++] = ch;
if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) {
putchar(ch);
count++;
buf[offset] = 0;
}
}
return (count_t) index;
return count;
}
 
/** Get character from device & echo it to screen */
uint8_t getc(chardev_t *chardev)
/** Get character from input device & echo it to screen */
wchar_t getc(indev_t *indev)
{
uint8_t ch;
 
ch = _getc(chardev);
wchar_t ch = indev_pop_character(indev);
putchar(ch);
return ch;
}
237,8 → 212,8
{
spinlock_lock(&klog_lock);
if ((klog_inited) && (klog_irq.notif_cfg.notify) && (klog_uspace > 0)) {
ipc_irq_send_msg_3(&klog_irq, klog_start, klog_len, klog_uspace);
if ((klog_inited) && (event_is_subscribed(EVENT_KLOG)) && (klog_uspace > 0)) {
event_notify_3(EVENT_KLOG, klog_start, klog_len, klog_uspace);
klog_uspace = 0;
}
245,27 → 220,27
spinlock_unlock(&klog_lock);
}
 
void putchar(char c)
void putchar(const wchar_t ch)
{
spinlock_lock(&klog_lock);
if ((klog_stored > 0) && (stdout->op->write)) {
if ((klog_stored > 0) && (stdout) && (stdout->op->write)) {
/* Print charaters stored in kernel log */
index_t i;
size_t i;
for (i = klog_len - klog_stored; i < klog_len; i++)
stdout->op->write(stdout, klog[(klog_start + i) % KLOG_SIZE]);
stdout->op->write(stdout, klog[(klog_start + i) % KLOG_LENGTH], silent);
klog_stored = 0;
}
/* Store character in the cyclic kernel log */
klog[(klog_start + klog_len) % KLOG_SIZE] = c;
if (klog_len < KLOG_SIZE)
klog[(klog_start + klog_len) % KLOG_LENGTH] = ch;
if (klog_len < KLOG_LENGTH)
klog_len++;
else
klog_start = (klog_start + 1) % KLOG_SIZE;
klog_start = (klog_start + 1) % KLOG_LENGTH;
if (stdout->op->write)
stdout->op->write(stdout, c);
if ((stdout) && (stdout->op->write))
stdout->op->write(stdout, ch, silent);
else {
/* The character is just in the kernel log */
if (klog_stored < klog_len)
278,7 → 253,7
/* Check notify uspace to update */
bool update;
if ((klog_uspace > KLOG_LATENCY) || (c == '\n'))
if ((klog_uspace > KLOG_LATENCY) || (ch == '\n'))
update = true;
else
update = false;
289,5 → 264,38
klog_update();
}
 
/** Print using kernel facility
*
* Print to kernel log.
*
*/
unative_t sys_klog(int fd, const void *buf, size_t size)
{
char *data;
int rc;
if (size > PAGE_SIZE)
return ELIMIT;
if (size > 0) {
data = (char *) malloc(size + 1, 0);
if (!data)
return ENOMEM;
rc = copy_from_uspace(data, buf, size);
if (rc) {
free(data);
return rc;
}
data[size] = 0;
printf("%s", data);
free(data);
} else
klog_update();
return size;
}
 
/** @}
*/
/branches/arm/kernel/generic/src/console/cmd.c
31,8 → 31,8
*/
 
/**
* @file cmd.c
* @brief Kernel console command wrappers.
* @file cmd.c
* @brief Kernel console command wrappers.
*
* This file is meant to contain all wrapper functions for
* all kconsole commands. The point is in separating
50,9 → 50,9
#include <arch.h>
#include <config.h>
#include <func.h>
#include <string.h>
#include <macros.h>
#include <debug.h>
#include <symtab.h>
#include <cpu.h>
#include <mm/tlb.h>
#include <arch/mm/tlb.h>
64,6 → 64,9
#include <proc/task.h>
#include <ipc/ipc.h>
#include <ipc/irq.h>
#include <ipc/event.h>
#include <symtab.h>
#include <errno.h>
 
#ifdef CONFIG_TEST
#include <test.h>
78,12 → 81,6
.argc = 0
};
 
static cmd_info_t exit_info = {
.name = "exit",
.description = "Exit kconsole.",
.argc = 0
};
 
static int cmd_reboot(cmd_arg_t *argv);
static cmd_info_t reboot_info = {
.name = "reboot",
456,7 → 453,6
&continue_info,
&cpus_info,
&desc_info,
&exit_info,
&reboot_info,
&uptime_info,
&halt_info,
501,7 → 497,7
for (i = 0; basic_commands[i]; i++) {
cmd_initialize(basic_commands[i]);
if (!cmd_register(basic_commands[i]))
panic("could not register command %s\n", basic_commands[i]->name);
printf("Cannot register command %s\n", basic_commands[i]->name);
}
}
 
514,23 → 510,31
*/
int cmd_help(cmd_arg_t *argv)
{
link_t *cur;
 
spinlock_lock(&cmd_lock);
link_t *cur;
size_t len = 0;
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
if (str_length(hlp->name) > len)
len = str_length(hlp->name);
spinlock_unlock(&hlp->lock);
}
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
printf("%s - %s\n", hlp->name, hlp->description);
 
printf("%-*s %s\n", len, hlp->name, hlp->description);
spinlock_unlock(&hlp->lock);
}
spinlock_unlock(&cmd_lock);
 
spinlock_unlock(&cmd_lock);
return 1;
}
 
578,7 → 582,7
int cmd_desc(cmd_arg_t *argv)
{
link_t *cur;
 
spinlock_lock(&cmd_lock);
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
586,8 → 590,8
hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
 
if (strncmp(hlp->name, (const char *) argv->buffer, strlen(hlp->name)) == 0) {
if (str_lcmp(hlp->name, (const char *) argv->buffer, str_length(hlp->name)) == 0) {
printf("%s - %s\n", hlp->name, hlp->description);
if (hlp->help)
hlp->help();
594,12 → 598,12
spinlock_unlock(&hlp->lock);
break;
}
 
spinlock_unlock(&hlp->lock);
}
spinlock_unlock(&cmd_lock);
 
return 1;
}
 
616,33 → 620,26
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(void);
#ifdef ia64
struct {
unative_t f;
unative_t gp;
} fptr;
#endif
unative_t (*fnc)(void);
fncptr_t fptr;
int rc;
 
symaddr = get_symbol_addr((char *) argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search((char *) argv->buffer);
symbol = (char *) argv->buffer;
rc = symtab_addr_lookup(symbol, &symaddr);
 
if (rc == ENOENT)
printf("Symbol %s not found.\n", symbol);
else if (rc == EOVERFLOW) {
symtab_print_search(symbol);
printf("Duplicate symbol, be more specific.\n");
} else if (rc == EOK) {
fnc = (unative_t (*)(void)) arch_construct_function(&fptr,
(void *) symaddr, (void *) cmd_call0);
printf("Calling %s() (%p)\n", symbol, symaddr);
printf("Result: %#" PRIxn "\n", fnc());
} else {
symbol = get_symtab_entry(symaddr);
printf("Calling %s() (%p)\n", symbol, symaddr);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(void)) &fptr;
#else
f = (unative_t (*)(void)) symaddr;
#endif
printf("Result: %#" PRIxn "\n", f());
printf("No symbol information available.\n");
}
return 1;
}
 
654,7 → 651,7
* call the function.
*/
count_t i;
size_t i;
for (i = 0; i < config.cpu_count; i++) {
if (!cpus[i].active)
continue;
680,35 → 677,27
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(unative_t,...);
unative_t (*fnc)(unative_t, ...);
unative_t arg1 = argv[1].intval;
#ifdef ia64
struct {
unative_t f;
unative_t gp;
} fptr;
#endif
fncptr_t fptr;
int rc;
 
symaddr = get_symbol_addr((char *) argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search((char *) argv->buffer);
symbol = (char *) argv->buffer;
rc = symtab_addr_lookup(symbol, &symaddr);
 
if (rc == ENOENT) {
printf("Symbol %s not found.\n", symbol);
} else if (rc == EOVERFLOW) {
symtab_print_search(symbol);
printf("Duplicate symbol, be more specific.\n");
} else if (rc == EOK) {
fnc = (unative_t (*)(unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call1);
printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, symaddr, symbol);
printf("Result: %#" PRIxn "\n", fnc(arg1));
} else {
symbol = get_symtab_entry(symaddr);
printf("No symbol information available.\n");
}
 
printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, symaddr, symbol);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(unative_t,...)) &fptr;
#else
f = (unative_t (*)(unative_t,...)) symaddr;
#endif
printf("Result: %#" PRIxn "\n", f(arg1));
}
return 1;
}
 
717,36 → 706,28
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(unative_t,unative_t,...);
unative_t (*fnc)(unative_t, unative_t, ...);
unative_t arg1 = argv[1].intval;
unative_t arg2 = argv[2].intval;
#ifdef ia64
struct {
unative_t f;
unative_t gp;
}fptr;
#endif
fncptr_t fptr;
int rc;
 
symaddr = get_symbol_addr((char *) argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search((char *) argv->buffer);
symbol = (char *) argv->buffer;
rc = symtab_addr_lookup(symbol, &symaddr);
 
if (rc == ENOENT) {
printf("Symbol %s not found.\n", symbol);
} else if (rc == EOVERFLOW) {
symtab_print_search(symbol);
printf("Duplicate symbol, be more specific.\n");
} else {
symbol = get_symtab_entry(symaddr);
} else if (rc == EOK) {
fnc = (unative_t (*)(unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call2);
printf("Calling f(%#" PRIxn ", %#" PRIxn "): %p: %s\n",
arg1, arg2, symaddr, symbol);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(unative_t,unative_t,...)) &fptr;
#else
f = (unative_t (*)(unative_t,unative_t,...)) symaddr;
#endif
printf("Result: %#" PRIxn "\n", f(arg1, arg2));
printf("Result: %#" PRIxn "\n", fnc(arg1, arg2));
} else {
printf("No symbol information available.\n");
}
return 1;
}
 
755,37 → 736,29
{
uintptr_t symaddr;
char *symbol;
unative_t (*f)(unative_t,unative_t,unative_t,...);
unative_t (*fnc)(unative_t, unative_t, unative_t, ...);
unative_t arg1 = argv[1].intval;
unative_t arg2 = argv[2].intval;
unative_t arg3 = argv[3].intval;
#ifdef ia64
struct {
unative_t f;
unative_t gp;
}fptr;
#endif
fncptr_t fptr;
int rc;
symbol = (char *) argv->buffer;
rc = symtab_addr_lookup(symbol, &symaddr);
 
symaddr = get_symbol_addr((char *) argv->buffer);
if (!symaddr)
printf("Symbol %s not found.\n", argv->buffer);
else if (symaddr == (uintptr_t) -1) {
symtab_print_search((char *) argv->buffer);
if (rc == ENOENT) {
printf("Symbol %s not found.\n", symbol);
} else if (rc == EOVERFLOW) {
symtab_print_search(symbol);
printf("Duplicate symbol, be more specific.\n");
} else {
symbol = get_symtab_entry(symaddr);
} else if (rc == EOK) {
fnc = (unative_t (*)(unative_t, unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call3);
printf("Calling f(%#" PRIxn ",%#" PRIxn ", %#" PRIxn "): %p: %s\n",
arg1, arg2, arg3, symaddr, symbol);
#ifdef ia64
fptr.f = symaddr;
fptr.gp = ((unative_t *)cmd_call2)[1];
f = (unative_t (*)(unative_t,unative_t,unative_t,...)) &fptr;
#else
f = (unative_t (*)(unative_t,unative_t,unative_t,...)) symaddr;
#endif
printf("Result: %#" PRIxn "\n", f(arg1, arg2, arg3));
printf("Result: %#" PRIxn "\n", fnc(arg1, arg2, arg3));
} else {
printf("No symbol information available.\n");
}
return 1;
}
 
835,30 → 808,34
/** Write 4 byte value to address */
int cmd_set4(cmd_arg_t *argv)
{
uint32_t *addr;
uintptr_t addr;
uint32_t arg1 = argv[1].intval;
bool pointer = false;
int rc;
 
if (((char *)argv->buffer)[0] == '*') {
addr = (uint32_t *) get_symbol_addr((char *) argv->buffer + 1);
rc = symtab_addr_lookup((char *) argv->buffer + 1, &addr);
pointer = true;
} else if (((char *) argv->buffer)[0] >= '0' &&
((char *)argv->buffer)[0] <= '9')
addr = (uint32_t *)atoi((char *)argv->buffer);
else
addr = (uint32_t *)get_symbol_addr((char *) argv->buffer);
((char *)argv->buffer)[0] <= '9') {
rc = EOK;
addr = atoi((char *)argv->buffer);
} else {
rc = symtab_addr_lookup((char *) argv->buffer, &addr);
}
 
if (!addr)
if (rc == ENOENT)
printf("Symbol %s not found.\n", argv->buffer);
else if (addr == (uint32_t *) -1) {
else if (rc == EOVERFLOW) {
symtab_print_search((char *) argv->buffer);
printf("Duplicate symbol, be more specific.\n");
} else {
} else if (rc == EOK) {
if (pointer)
addr = (uint32_t *)(*(unative_t *)addr);
addr = *(uintptr_t *) addr;
printf("Writing %#" PRIx64 " -> %p\n", arg1, addr);
*addr = arg1;
*(uint32_t *) addr = arg1;
} else {
printf("No symbol information available.\n");
}
return 1;
976,8 → 953,11
int cmd_continue(cmd_arg_t *argv)
{
printf("The kernel will now relinquish the console.\n");
printf("Use userspace controls to redraw the screen.\n");
arch_release_console();
release_console();
event_notify_0(EVENT_KCONSOLE);
indev_pop_character(stdin);
return 1;
}
 
990,18 → 970,23
*/
int cmd_tests(cmd_arg_t *argv)
{
size_t len = 0;
test_t *test;
for (test = tests; test->name != NULL; test++) {
if (str_length(test->name) > len)
len = str_length(test->name);
}
for (test = tests; test->name != NULL; test++)
printf("%s\t\t%s%s\n", test->name, test->desc, (test->safe ? "" : " (unsafe)"));
printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)"));
printf("*\t\tRun all safe tests\n");
printf("%-*s Run all safe tests\n", len, "*");
return 1;
}
 
static bool run_test(const test_t *test)
{
printf("%s\t\t%s\n", test->name, test->desc);
printf("%s (%s)\n", test->name, test->desc);
/* Update and read thread accounting
for benchmarking */
1012,7 → 997,8
interrupts_restore(ipl);
/* Execute the test */
char * ret = test->entry(false);
test_quiet = false;
char *ret = test->entry();
/* Update and read thread accounting */
ipl = interrupts_disable();
1064,7 → 1050,8
interrupts_restore(ipl);
/* Execute the test */
char * ret = test->entry(true);
test_quiet = true;
char * ret = test->entry();
/* Update and read thread accounting */
ipl = interrupts_disable();
1112,7 → 1099,7
{
test_t *test;
if (strcmp((char *) argv->buffer, "*") == 0) {
if (str_cmp((char *) argv->buffer, "*") == 0) {
for (test = tests; test->name != NULL; test++) {
if (test->safe) {
printf("\n");
1124,7 → 1111,7
bool fnd = false;
for (test = tests; test->name != NULL; test++) {
if (strcmp(test->name, (char *) argv->buffer) == 0) {
if (str_cmp(test->name, (char *) argv->buffer) == 0) {
fnd = true;
run_test(test);
break;
1149,24 → 1136,33
test_t *test;
uint32_t cnt = argv[1].intval;
bool fnd = false;
for (test = tests; test->name != NULL; test++) {
if (strcmp(test->name, (char *) argv->buffer) == 0) {
fnd = true;
if (test->safe)
run_bench(test, cnt);
else
printf("Unsafe test\n");
break;
if (str_cmp((char *) argv->buffer, "*") == 0) {
for (test = tests; test->name != NULL; test++) {
if (test->safe) {
if (!run_bench(test, cnt))
break;
}
}
} else {
bool fnd = false;
for (test = tests; test->name != NULL; test++) {
if (str_cmp(test->name, (char *) argv->buffer) == 0) {
fnd = true;
if (test->safe)
run_bench(test, cnt);
else
printf("Unsafe test\n");
break;
}
}
if (!fnd)
printf("Unknown test\n");
}
if (!fnd)
printf("Unknown test\n");
 
return 1;
}
 
/branches/arm/kernel/generic/src/console/kconsole.c
31,10 → 31,11
*/
 
/**
* @file kconsole.c
* @brief Kernel console.
* @file kconsole.c
* @brief Kernel console.
*
* This file contains kernel thread managing the kernel console.
*
*/
 
#include <console/kconsole.h>
49,8 → 50,14
#include <macros.h>
#include <debug.h>
#include <func.h>
#include <string.h>
#include <macros.h>
#include <sysinfo/sysinfo.h>
#include <ddi/device.h>
#include <symtab.h>
#include <macros.h>
#include <errno.h>
#include <putchar.h>
#include <string.h>
 
/** Simple kernel console.
*
59,7 → 66,7
* but makes it possible for other kernel subsystems to
* register their own commands.
*/
 
/** Locking.
*
* There is a list of cmd_info_t structures. This list
74,33 → 81,36
* When locking two cmd info structures, structure with
* lower address must be locked first.
*/
SPINLOCK_INITIALIZE(cmd_lock); /**< Lock protecting command list. */
LIST_INITIALIZE(cmd_head); /**< Command list. */
 
static cmd_info_t *parse_cmdline(char *cmdline, size_t len);
static bool parse_argument(char *cmdline, size_t len, index_t *start,
index_t *end);
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
SPINLOCK_INITIALIZE(cmd_lock); /**< Lock protecting command list. */
LIST_INITIALIZE(cmd_head); /**< Command list. */
 
/** Initialize kconsole data structures. */
static wchar_t history[KCONSOLE_HISTORY][MAX_CMDLINE] = {};
static size_t history_pos = 0;
 
/** Initialize kconsole data structures
*
* This is the most basic initialization, almost no
* other kernel subsystem is ready yet.
*
*/
void kconsole_init(void)
{
int i;
 
unsigned int i;
cmd_init();
for (i = 0; i < KCONSOLE_HISTORY; i++)
history[i][0] = '\0';
history[i][0] = 0;
}
 
 
/** Register kconsole command.
*
* @param cmd Structure describing the command.
*
* @return 0 on failure, 1 on success.
* @return False on failure, true on success.
*
*/
int cmd_register(cmd_info_t *cmd)
bool cmd_register(cmd_info_t *cmd)
{
link_t *cur;
110,16 → 120,14
* Make sure the command is not already listed.
*/
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
hlp = list_get_instance(cur, cmd_info_t, link);
 
if (hlp == cmd) {
/* The command is already there. */
spinlock_unlock(&cmd_lock);
return 0;
return false;
}
 
/* Avoid deadlock. */
if (hlp < cmd) {
spinlock_lock(&hlp->lock);
128,13 → 136,13
spinlock_lock(&cmd->lock);
spinlock_lock(&hlp->lock);
}
if ((strncmp(hlp->name, cmd->name, max(strlen(cmd->name),
strlen(hlp->name))) == 0)) {
if (str_cmp(hlp->name, cmd->name) == 0) {
/* The command is already there. */
spinlock_unlock(&hlp->lock);
spinlock_unlock(&cmd->lock);
spinlock_unlock(&cmd_lock);
return 0;
return false;
}
spinlock_unlock(&hlp->lock);
147,294 → 155,274
list_append(&cmd->link, &cmd_head);
spinlock_unlock(&cmd_lock);
return 1;
return true;
}
 
/** Print count times a character */
static void rdln_print_c(char ch, int count)
static void print_cc(wchar_t ch, size_t count)
{
int i;
size_t i;
for (i = 0; i < count; i++)
putchar(ch);
}
 
/** Insert character to string */
static void insert_char(char *str, char ch, int pos)
/** Try to find a command beginning with prefix */
static const char *cmdtab_search_one(const char *name, link_t **startpos)
{
int i;
size_t namelen = str_length(name);
for (i = strlen(str); i > pos; i--)
str[i] = str[i - 1];
str[pos] = ch;
}
 
/** Try to find a command beginning with prefix */
static const char *cmdtab_search_one(const char *name,link_t **startpos)
{
size_t namelen = strlen(name);
const char *curname;
 
spinlock_lock(&cmd_lock);
 
if (!*startpos)
if (*startpos == NULL)
*startpos = cmd_head.next;
 
for (; *startpos != &cmd_head; *startpos = (*startpos)->next) {
cmd_info_t *hlp;
hlp = list_get_instance(*startpos, cmd_info_t, link);
 
curname = hlp->name;
if (strlen(curname) < namelen)
cmd_info_t *hlp = list_get_instance(*startpos, cmd_info_t, link);
const char *curname = hlp->name;
if (str_length(curname) < namelen)
continue;
if (strncmp(curname, name, namelen) == 0) {
spinlock_unlock(&cmd_lock);
return curname+namelen;
if (str_lcmp(curname, name, namelen) == 0) {
spinlock_unlock(&cmd_lock);
return (curname + str_lsize(curname, namelen));
}
}
spinlock_unlock(&cmd_lock);
spinlock_unlock(&cmd_lock);
return NULL;
}
 
 
/** Command completion of the commands
/** Command completion of the commands
*
* @param name - string to match, changed to hint on exit
* @return number of found matches
* @param name String to match, changed to hint on exit
* @param size Input buffer size
*
* @return Number of found matches
*
*/
static int cmdtab_compl(char *name)
static int cmdtab_compl(char *input, size_t size)
{
static char output[MAX_SYMBOL_NAME + 1];
link_t *startpos = NULL;
const char *foundtxt;
int found = 0;
int i;
 
output[0] = '\0';
while ((foundtxt = cmdtab_search_one(name, &startpos))) {
startpos = startpos->next;
if (!found)
strncpy(output, foundtxt, strlen(foundtxt) + 1);
else {
for (i = 0; output[i] && foundtxt[i] &&
output[i] == foundtxt[i]; i++)
;
output[i] = '\0';
}
const char *name = input;
size_t found = 0;
link_t *pos = NULL;
const char *hint;
char output[MAX_CMDLINE];
output[0] = 0;
while ((hint = cmdtab_search_one(name, &pos))) {
if ((found == 0) || (str_length(output) > str_length(hint)))
str_cpy(output, MAX_CMDLINE, hint);
pos = pos->next;
found++;
}
if (!found)
return 0;
 
if (found > 1 && !strlen(output)) {
if ((found > 1) && (str_length(output) != 0)) {
printf("\n");
startpos = NULL;
while ((foundtxt = cmdtab_search_one(name, &startpos))) {
cmd_info_t *hlp;
hlp = list_get_instance(startpos, cmd_info_t, link);
printf("%s - %s\n", hlp->name, hlp->description);
startpos = startpos->next;
pos = NULL;
while ((hint = cmdtab_search_one(name, &pos))) {
cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link);
printf("%s (%s)\n", hlp->name, hlp->description);
pos = pos->next;
}
}
strncpy(name, output, MAX_SYMBOL_NAME);
if (found > 0)
str_cpy(input, size, output);
return found;
}
 
static char *clever_readline(const char *prompt, chardev_t *input)
static wchar_t *clever_readline(const char *prompt, indev_t *indev)
{
static int histposition = 0;
 
static char tmp[MAX_CMDLINE + 1];
int curlen = 0, position = 0;
char *current = history[histposition];
int i;
char mod; /* Command Modifier */
char c;
 
printf("%s> ", prompt);
while (1) {
c = _getc(input);
if (c == '\n') {
putchar(c);
size_t position = 0;
wchar_t *current = history[history_pos];
current[0] = 0;
while (true) {
wchar_t ch = indev_pop_character(indev);
if (ch == '\n') {
/* Enter */
putchar(ch);
break;
}
if (c == '\b') { /* Backspace */
if (ch == '\b') {
/* Backspace */
if (position == 0)
continue;
for (i = position; i < curlen; i++)
current[i - 1] = current[i];
curlen--;
position--;
putchar('\b');
for (i = position; i < curlen; i++)
putchar(current[i]);
putchar(' ');
rdln_print_c('\b', curlen - position + 1);
continue;
if (wstr_remove(current, position - 1)) {
position--;
putchar('\b');
printf("%ls ", current + position);
print_cc('\b', wstr_length(current) - position + 1);
continue;
}
}
if (c == '\t') { /* Tabulator */
int found;
 
if (ch == '\t') {
/* Tab completion */
/* Move to the end of the word */
for (; position < curlen && current[position] != ' ';
for (; (current[position] != 0) && (!isspace(current[position]));
position++)
putchar(current[position]);
/* Copy to tmp last word */
for (i = position - 1; i >= 0 && current[i] != ' '; i--)
;
/* If word begins with * or &, skip it */
if (tmp[0] == '*' || tmp[0] == '&')
for (i = 1; tmp[i]; i++)
tmp[i - 1] = tmp[i];
i++; /* I is at the start of the word */
strncpy(tmp, current + i, position - i + 1);
 
if (i == 0) { /* Command completion */
found = cmdtab_compl(tmp);
} else { /* Symtab completion */
found = symtab_compl(tmp);
if (position == 0)
continue;
/* Find the beginning of the word
and copy it to tmp */
size_t beg;
for (beg = position - 1; (beg > 0) && (!isspace(current[beg]));
beg--);
if (isspace(current[beg]))
beg++;
char tmp[STR_BOUNDS(MAX_CMDLINE)];
wstr_nstr(tmp, current + beg, position - beg + 1);
int found;
if (beg == 0) {
/* Command completion */
found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
} else {
/* Symbol completion */
found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE));
}
 
if (found == 0)
if (found == 0)
continue;
for (i = 0; tmp[i] && curlen < MAX_CMDLINE;
i++, curlen++)
insert_char(current, tmp[i], i + position);
 
if (strlen(tmp) || found == 1) { /* If we have a hint */
for (i = position; i < curlen; i++)
putchar(current[i]);
position += strlen(tmp);
/* Add space to end */
if (found == 1 && position == curlen &&
curlen < MAX_CMDLINE) {
current[position] = ' ';
curlen++;
if (found > 1) {
/* No unique hint, list was printed */
printf("%s> ", prompt);
printf("%ls", current);
print_cc('\b', wstr_length(current) - position);
continue;
}
/* We have a hint */
size_t off = 0;
size_t i = 0;
while ((ch = str_decode(tmp, &off, STR_NO_LIMIT)) != 0) {
if (!wstr_linsert(current, ch, position + i, MAX_CMDLINE))
break;
i++;
}
printf("%ls", current + position);
position += str_length(tmp);
print_cc('\b', wstr_length(current) - position);
if (position == wstr_length(current)) {
/* Insert a space after the last completed argument */
if (wstr_linsert(current, ' ', position, MAX_CMDLINE)) {
printf("%ls", current + position);
position++;
putchar(' ');
}
} else { /* No hint, table was printed */
printf("%s> ", prompt);
for (i = 0; i < curlen; i++)
putchar(current[i]);
position += strlen(tmp);
}
rdln_print_c('\b', curlen - position);
continue;
}
if (c == 0x1b) { /* Special command */
mod = _getc(input);
c = _getc(input);
 
if (mod != 0x5b && mod != 0x4f)
continue;
 
if (c == 0x33 && _getc(input) == 0x7e) {
/* Delete */
if (position == curlen)
continue;
for (i = position + 1; i < curlen; i++) {
putchar(current[i]);
current[i - 1] = current[i];
}
putchar(' ');
rdln_print_c('\b', curlen - position);
curlen--;
} else if (c == 0x48) { /* Home */
rdln_print_c('\b', position);
position = 0;
} else if (c == 0x46) { /* End */
for (i = position; i < curlen; i++)
putchar(current[i]);
position = curlen;
} else if (c == 0x44) { /* Left */
if (position > 0) {
putchar('\b');
position--;
}
continue;
} else if (c == 0x43) { /* Right */
if (position < curlen) {
putchar(current[position]);
position++;
}
continue;
} else if (c == 0x41 || c == 0x42) {
/* Up, down */
rdln_print_c('\b', position);
rdln_print_c(' ', curlen);
rdln_print_c('\b', curlen);
if (c == 0x41) /* Up */
histposition--;
if (ch == U_LEFT_ARROW) {
/* Left */
if (position > 0) {
putchar('\b');
position--;
}
continue;
}
if (ch == U_RIGHT_ARROW) {
/* Right */
if (position < wstr_length(current)) {
putchar(current[position]);
position++;
}
continue;
}
if ((ch == U_UP_ARROW) || (ch == U_DOWN_ARROW)) {
/* Up, down */
print_cc('\b', position);
print_cc(' ', wstr_length(current));
print_cc('\b', wstr_length(current));
if (ch == U_UP_ARROW) {
/* Up */
if (history_pos == 0)
history_pos = KCONSOLE_HISTORY - 1;
else
histposition++;
if (histposition < 0) {
histposition = KCONSOLE_HISTORY - 1;
} else {
histposition =
histposition % KCONSOLE_HISTORY;
}
current = history[histposition];
printf("%s", current);
curlen = strlen(current);
position = curlen;
history_pos--;
} else {
/* Down */
history_pos++;
history_pos = history_pos % KCONSOLE_HISTORY;
}
current = history[history_pos];
printf("%ls", current);
position = wstr_length(current);
continue;
}
if (ch == U_HOME_ARROW) {
/* Home */
print_cc('\b', position);
position = 0;
continue;
}
if (ch == U_END_ARROW) {
/* End */
printf("%ls", current + position);
position = wstr_length(current);
continue;
}
if (ch == U_DELETE) {
/* Delete */
if (position == wstr_length(current))
continue;
if (wstr_remove(current, position)) {
printf("%ls ", current + position);
print_cc('\b', wstr_length(current) - position + 1);
}
continue;
}
if (curlen >= MAX_CMDLINE)
continue;
 
insert_char(current, c, position);
 
curlen++;
for (i = position; i < curlen; i++)
putchar(current[i]);
position++;
rdln_print_c('\b',curlen - position);
}
if (curlen) {
histposition++;
histposition = histposition % KCONSOLE_HISTORY;
if (wstr_linsert(current, ch, position, MAX_CMDLINE)) {
printf("%ls", current + position);
position++;
print_cc('\b', wstr_length(current) - position);
}
}
current[curlen] = '\0';
if (wstr_length(current) > 0) {
history_pos++;
history_pos = history_pos % KCONSOLE_HISTORY;
}
return current;
}
 
/** Kernel console managing thread.
*
* @param prompt Kernel console prompt (e.g kconsole/panic).
*/
void kconsole(void *prompt)
bool kconsole_check_poll(void)
{
cmd_info_t *cmd_info;
count_t len;
char *cmdline;
 
if (!stdin) {
printf("%s: no stdin\n", __func__);
return;
}
while (true) {
cmdline = clever_readline((char *) prompt, stdin);
len = strlen(cmdline);
if (!len)
continue;
cmd_info = parse_cmdline(cmdline, len);
if (!cmd_info)
continue;
if (strncmp(cmd_info->name, "exit",
min(strlen(cmd_info->name), 5)) == 0)
break;
(void) cmd_info->func(cmd_info->argv);
}
return check_poll(stdin);
}
 
static int parse_int_arg(char *text, size_t len, unative_t *result)
static bool parse_int_arg(const char *text, size_t len, unative_t *result)
{
static char symname[MAX_SYMBOL_NAME];
uintptr_t symaddr;
bool isaddr = false;
bool isptr = false;
448,63 → 436,113
text++;
len--;
}
if (text[0] < '0' || text[0] > '9') {
strncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME));
symaddr = get_symbol_addr(symname);
if (!symaddr) {
if ((text[0] < '0') || (text[0] > '9')) {
char symname[MAX_SYMBOL_NAME];
str_ncpy(symname, MAX_SYMBOL_NAME, text, len + 1);
uintptr_t symaddr;
int rc = symtab_addr_lookup(symname, &symaddr);
switch (rc) {
case ENOENT:
printf("Symbol %s not found.\n", symname);
return -1;
}
if (symaddr == (uintptr_t) -1) {
return false;
case EOVERFLOW:
printf("Duplicate symbol %s.\n", symname);
symtab_print_search(symname);
return -1;
return false;
case ENOTSUP:
printf("No symbol information available.\n");
return false;
}
if (isaddr)
*result = (unative_t)symaddr;
*result = (unative_t) symaddr;
else if (isptr)
*result = **((unative_t **)symaddr);
*result = **((unative_t **) symaddr);
else
*result = *((unative_t *)symaddr);
} else { /* It's a number - convert it */
*result = *((unative_t *) symaddr);
} else {
/* It's a number - convert it */
*result = atoi(text);
if (isptr)
*result = *((unative_t *)*result);
*result = *((unative_t *) *result);
}
return true;
}
 
return 0;
/** Parse argument.
*
* Find start and end positions of command line argument.
*
* @param cmdline Command line as read from the input device.
* @param size Size (in bytes) of the string.
* @param start On entry, 'start' contains pointer to the offset
* of the first unprocessed character of cmdline.
* On successful exit, it marks beginning of the next argument.
* @param end Undefined on entry. On exit, 'end' is the offset of the first
* character behind the next argument.
*
* @return False on failure, true on success.
*
*/
static bool parse_argument(const char *cmdline, size_t size, size_t *start, size_t *end)
{
ASSERT(start != NULL);
ASSERT(end != NULL);
bool found_start = false;
size_t offset = *start;
size_t prev = *start;
wchar_t ch;
while ((ch = str_decode(cmdline, &offset, size)) != 0) {
if (!found_start) {
if (!isspace(ch)) {
*start = prev;
found_start = true;
}
} else {
if (isspace(ch))
break;
}
prev = offset;
}
*end = prev;
return found_start;
}
 
/** Parse command line.
*
* @param cmdline Command line as read from input device.
* @param len Command line length.
* @param cmdline Command line as read from input device.
* @param size Size (in bytes) of the string.
*
* @return Structure describing the command.
*
*/
cmd_info_t *parse_cmdline(char *cmdline, size_t len)
static cmd_info_t *parse_cmdline(const char *cmdline, size_t size)
{
index_t start = 0, end = 0;
cmd_info_t *cmd = NULL;
link_t *cur;
count_t i;
int error = 0;
if (!parse_argument(cmdline, len, &start, &end)) {
size_t start = 0;
size_t end = 0;
if (!parse_argument(cmdline, size, &start, &end)) {
/* Command line did not contain alphanumeric word. */
return NULL;
}
 
spinlock_lock(&cmd_lock);
cmd_info_t *cmd = NULL;
link_t *cur;
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) {
cmd_info_t *hlp;
hlp = list_get_instance(cur, cmd_info_t, link);
cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link);
spinlock_lock(&hlp->lock);
if (strncmp(hlp->name, &cmdline[start], max(strlen(hlp->name),
end - start + 1)) == 0) {
if (str_lcmp(hlp->name, cmdline + start,
max(str_length(hlp->name),
str_nlength(cmdline + start, (size_t) (end - start) - 1))) == 0) {
cmd = hlp;
break;
}
512,7 → 550,7
spinlock_unlock(&hlp->lock);
}
spinlock_unlock(&cmd_lock);
spinlock_unlock(&cmd_lock);
if (!cmd) {
/* Unknown command. */
519,7 → 557,7
printf("Unknown command.\n");
return NULL;
}
 
/* cmd == hlp is locked */
/*
528,52 → 566,54
* converted to those specified in the cmd info
* structure.
*/
 
bool error = false;
size_t i;
for (i = 0; i < cmd->argc; i++) {
char *buf;
start = end + 1;
if (!parse_argument(cmdline, len, &start, &end)) {
start = end;
if (!parse_argument(cmdline, size, &start, &end)) {
printf("Too few arguments.\n");
spinlock_unlock(&cmd->lock);
return NULL;
}
error = 0;
char *buf;
switch (cmd->argv[i].type) {
case ARG_TYPE_STRING:
buf = (char *) cmd->argv[i].buffer;
strncpy(buf, (const char *) &cmdline[start],
min((end - start) + 2, cmd->argv[i].len));
buf[min((end - start) + 1, cmd->argv[i].len - 1)] =
'\0';
str_ncpy(buf, cmd->argv[i].len, cmdline + start,
end - start);
break;
case ARG_TYPE_INT:
if (parse_int_arg(cmdline + start, end - start + 1,
case ARG_TYPE_INT:
if (!parse_int_arg(cmdline + start, end - start,
&cmd->argv[i].intval))
error = 1;
error = true;
break;
case ARG_TYPE_VAR:
if (start != end && cmdline[start] == '"' &&
cmdline[end] == '"') {
buf = (char *) cmd->argv[i].buffer;
strncpy(buf, (const char *) &cmdline[start + 1],
min((end-start), cmd->argv[i].len));
buf[min((end - start), cmd->argv[i].len - 1)] =
'\0';
cmd->argv[i].intval = (unative_t) buf;
cmd->argv[i].vartype = ARG_TYPE_STRING;
} else if (!parse_int_arg(cmdline + start,
end - start + 1, &cmd->argv[i].intval)) {
if ((start < end - 1) && (cmdline[start] == '"')) {
if (cmdline[end - 1] == '"') {
buf = (char *) cmd->argv[i].buffer;
str_ncpy(buf, cmd->argv[i].len,
cmdline + start + 1,
(end - start) - 1);
cmd->argv[i].intval = (unative_t) buf;
cmd->argv[i].vartype = ARG_TYPE_STRING;
} else {
printf("Wrong synxtax.\n");
error = true;
}
} else if (parse_int_arg(cmdline + start,
end - start, &cmd->argv[i].intval)) {
cmd->argv[i].vartype = ARG_TYPE_INT;
} else {
printf("Unrecognized variable argument.\n");
error = 1;
error = true;
}
break;
case ARG_TYPE_INVALID:
default:
printf("invalid argument type\n");
error = 1;
printf("Invalid argument type\n");
error = true;
break;
}
}
583,8 → 623,8
return NULL;
}
start = end + 1;
if (parse_argument(cmdline, len, &start, &end)) {
start = end;
if (parse_argument(cmdline, size, &start, &end)) {
printf("Too many arguments.\n");
spinlock_unlock(&cmd->lock);
return NULL;
594,42 → 634,55
return cmd;
}
 
/** Parse argument.
/** Kernel console prompt.
*
* Find start and end positions of command line argument.
* @param prompt Kernel console prompt (e.g kconsole/panic).
* @param msg Message to display in the beginning.
* @param kcon Wait for keypress to show the prompt
* and never exit.
*
* @param cmdline Command line as read from the input device.
* @param len Number of characters in cmdline.
* @param start On entry, 'start' contains pointer to the index
* of first unprocessed character of cmdline.
* On successful exit, it marks beginning of the next argument.
* @param end Undefined on entry. On exit, 'end' points to the last character
* of the next argument.
*
* @return false on failure, true on success.
*/
bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end)
void kconsole(char *prompt, char *msg, bool kcon)
{
index_t i;
bool found_start = false;
if (!stdin) {
LOG("No stdin for kernel console");
return;
}
ASSERT(start != NULL);
ASSERT(end != NULL);
if (msg)
printf("%s", msg);
for (i = *start; i < len; i++) {
if (!found_start) {
if (isspace(cmdline[i]))
(*start)++;
else
found_start = true;
} else {
if (isspace(cmdline[i]))
break;
}
if (kcon)
indev_pop_character(stdin);
else
printf("Type \"exit\" to leave the console.\n");
while (true) {
wchar_t *tmp = clever_readline((char *) prompt, stdin);
size_t len = wstr_length(tmp);
if (!len)
continue;
char cmdline[STR_BOUNDS(MAX_CMDLINE)];
wstr_nstr(cmdline, tmp, STR_BOUNDS(MAX_CMDLINE));
if ((!kcon) && (len == 4) && (str_lcmp(cmdline, "exit", 4) == 0))
break;
cmd_info_t *cmd_info = parse_cmdline(cmdline, STR_BOUNDS(MAX_CMDLINE));
if (!cmd_info)
continue;
(void) cmd_info->func(cmd_info->argv);
}
*end = i - 1;
}
 
return found_start;
/** Kernel console managing thread.
*
*/
void kconsole_thread(void *data)
{
kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true);
}
 
/** @}
/branches/arm/kernel/generic/src/console/chardev.c
33,46 → 33,119
*/
 
#include <console/chardev.h>
#include <putchar.h>
#include <synch/waitq.h>
#include <synch/spinlock.h>
#include <print.h>
#include <func.h>
#include <arch.h>
 
/** Initialize character device.
/** Initialize input character device.
*
* @param chardev Character device.
* @param op Implementation of character device operations.
* @param indev Input character device.
* @param op Implementation of input character device operations.
*
*/
void chardev_initialize(char *name, chardev_t *chardev,
chardev_operations_t *op)
void indev_initialize(char *name, indev_t *indev,
indev_operations_t *op)
{
chardev->name = name;
 
waitq_initialize(&chardev->wq);
spinlock_initialize(&chardev->lock, "chardev");
chardev->counter = 0;
chardev->index = 0;
chardev->op = op;
indev->name = name;
waitq_initialize(&indev->wq);
spinlock_initialize(&indev->lock, "indev");
indev->counter = 0;
indev->index = 0;
indev->op = op;
}
 
/** Push character read from input character device.
*
* @param chardev Character device.
* @param ch Character being pushed.
* @param indev Input character device.
* @param ch Character being pushed.
*
*/
void chardev_push_character(chardev_t *chardev, uint8_t ch)
void indev_push_character(indev_t *indev, wchar_t ch)
{
spinlock_lock(&chardev->lock);
chardev->counter++;
if (chardev->counter == CHARDEV_BUFLEN - 1) {
/* buffer full => disable device interrupt */
chardev->op->suspend(chardev);
ASSERT(indev);
spinlock_lock(&indev->lock);
if (indev->counter == INDEV_BUFLEN - 1) {
/* Buffer full */
spinlock_unlock(&indev->lock);
return;
}
chardev->buffer[chardev->index++] = ch;
chardev->index = chardev->index % CHARDEV_BUFLEN; /* index modulo size of buffer */
waitq_wakeup(&chardev->wq, WAKEUP_FIRST);
spinlock_unlock(&chardev->lock);
indev->counter++;
indev->buffer[indev->index++] = ch;
/* Index modulo size of buffer */
indev->index = indev->index % INDEV_BUFLEN;
waitq_wakeup(&indev->wq, WAKEUP_FIRST);
spinlock_unlock(&indev->lock);
}
 
/** Pop character from input character device.
*
* @param indev Input character device.
*
* @return Character read.
*
*/
wchar_t indev_pop_character(indev_t *indev)
{
if (atomic_get(&haltstate)) {
/* If we are here, we are hopefully on the processor that
* issued the 'halt' command, so proceed to read the character
* directly from input
*/
if (check_poll(indev))
return indev->op->poll(indev);
/* No other way of interacting with user */
interrupts_disable();
if (CPU)
printf("cpu%u: ", CPU->id);
else
printf("cpu: ");
printf("halted (no polling input)\n");
cpu_halt();
}
waitq_sleep(&indev->wq);
ipl_t ipl = interrupts_disable();
spinlock_lock(&indev->lock);
wchar_t ch = indev->buffer[(indev->index - indev->counter) % INDEV_BUFLEN];
indev->counter--;
spinlock_unlock(&indev->lock);
interrupts_restore(ipl);
return ch;
}
 
/** Initialize output character device.
*
* @param outdev Output character device.
* @param op Implementation of output character device operations.
*
*/
void outdev_initialize(char *name, outdev_t *outdev,
outdev_operations_t *op)
{
outdev->name = name;
spinlock_initialize(&outdev->lock, "outdev");
outdev->op = op;
}
 
bool check_poll(indev_t *indev)
{
if (indev == NULL)
return false;
if (indev->op == NULL)
return false;
return (indev->op->poll != NULL);
}
 
/** @}
*/
/branches/arm/kernel/generic/src/proc/scheduler.c
451,7 → 451,7
/*
* Entering state is unexpected.
*/
panic("tid%" PRIu64 ": unexpected state %s\n",
panic("tid%" PRIu64 ": unexpected state %s.",
THREAD->tid, thread_states[THREAD->state]);
break;
}
708,7 → 708,7
continue;
 
spinlock_lock(&cpus[cpu].lock);
printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIc "\n",
printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIs "\n",
cpus[cpu].id, &cpus[cpu], atomic_get(&cpus[cpu].nrdy),
cpus[cpu].needs_relink);
/branches/arm/kernel/generic/src/proc/task.c
52,7 → 52,10
#include <print.h>
#include <errno.h>
#include <func.h>
#include <string.h>
#include <syscall/copy.h>
#include <macros.h>
#include <ipc/event.h>
 
/** Spinlock protecting the tasks_tree AVL tree. */
SPINLOCK_INITIALIZE(tasks_lock);
130,7 → 133,7
/** Create new task with no threads.
*
* @param as Task's address space.
* @param name Symbolic name.
* @param name Symbolic name (a copy is made).
*
* @return New task's structure.
*
148,7 → 151,10
spinlock_initialize(&ta->lock, "task_ta_lock");
list_initialize(&ta->th_head);
ta->as = as;
ta->name = name;
 
memcpy(ta->name, name, TASK_NAME_BUFLEN);
ta->name[TASK_NAME_BUFLEN - 1] = 0;
 
atomic_set(&ta->refcount, 0);
atomic_set(&ta->lifecount, 0);
ta->context = CONTEXT;
161,10 → 167,10
udebug_task_init(&ta->udebug);
 
/* Init kbox stuff */
ipc_answerbox_init(&ta->kernel_box, ta);
ta->kb_thread = NULL;
mutex_initialize(&ta->kb_cleanup_lock, MUTEX_PASSIVE);
ta->kb_finished = false;
ipc_answerbox_init(&ta->kb.box, ta);
ta->kb.thread = NULL;
mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE);
ta->kb.finished = false;
#endif
 
ipc_answerbox_init(&ta->answerbox, ta);
192,7 → 198,14
avltree_insert(&tasks_tree, &ta->tasks_tree_node);
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
 
/*
* Notify about task creation.
*/
if (event_is_subscribed(EVENT_WAIT))
event_notify_3(EVENT_WAIT, TASK_CREATE, LOWER32(ta->taskid),
UPPER32(ta->taskid));
return ta;
}
 
225,6 → 238,13
if (atomic_predec(&t->as->refcount) == 0)
as_destroy(t->as);
/*
* Notify about task destruction.
*/
if (event_is_subscribed(EVENT_WAIT))
event_notify_3(EVENT_WAIT, TASK_DESTROY, LOWER32(t->taskid),
UPPER32(t->taskid));
free(t);
TASK = NULL;
}
246,6 → 266,35
sizeof(TASK->taskid));
}
 
/** Syscall for setting the task name.
*
* The name simplifies identifying the task in the task list.
*
* @param name The new name for the task. (typically the same
* as the command used to execute it).
*
* @return 0 on success or an error code from @ref errno.h.
*/
unative_t sys_task_set_name(const char *uspace_name, size_t name_len)
{
int rc;
char namebuf[TASK_NAME_BUFLEN];
 
/* Cap length of name and copy it from userspace. */
 
if (name_len > TASK_NAME_BUFLEN - 1)
name_len = TASK_NAME_BUFLEN - 1;
 
rc = copy_from_uspace(namebuf, uspace_name, name_len);
if (rc != 0)
return (unative_t) rc;
 
namebuf[name_len] = '\0';
str_cpy(TASK->name, TASK_NAME_BUFLEN, namebuf);
 
return EOK;
}
 
/** Find task structure corresponding to task ID.
*
* The tasks_lock must be already held by the caller of this function and
336,7 → 385,7
bool sleeping = false;
thr = list_get_instance(cur, thread_t, th_link);
spinlock_lock(&thr->lock);
thr->interrupted = true;
if (thr->state == Sleeping)
364,13 → 413,13
order(task_get_accounting(t), &cycles, &suffix);
 
#ifdef __32_BITS__
printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %10p %10p %9" PRIu64
printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %10p %10p %9" PRIu64
"%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles,
suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls));
#endif
 
#ifdef __64_BITS__
printf("%-6" PRIu64 " %-10s %-3" PRIu32 " %18p %18p %9" PRIu64
printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %18p %18p %9" PRIu64
"%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles,
suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls));
#endif
395,16 → 444,16
spinlock_lock(&tasks_lock);
 
#ifdef __32_BITS__
printf("taskid name ctx address as "
printf("taskid name ctx address as "
"cycles threads calls callee\n");
printf("------ ---------- --- ---------- ---------- "
printf("------ ------------ --- ---------- ---------- "
"---------- ------- ------ ------>\n");
#endif
 
#ifdef __64_BITS__
printf("taskid name ctx address as "
printf("taskid name ctx address as "
"cycles threads calls callee\n");
printf("------ ---------- --- ------------------ ------------------ "
printf("------ ------------ --- ------------------ ------------------ "
"---------- ------- ------ ------>\n");
#endif
 
/branches/arm/kernel/generic/src/proc/program.c
67,9 → 67,10
*
* @param as Address space containing a binary program image.
* @param entry_addr Program entry-point address in program address space.
* @param name Name to set for the program's task.
* @param p Buffer for storing program information.
*/
void program_create(as_t *as, uintptr_t entry_addr, program_t *p)
void program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *p)
{
as_area_t *a;
uspace_arg_t *kernel_uarg;
81,7 → 82,7
kernel_uarg->uspace_thread_arg = NULL;
kernel_uarg->uspace_uarg = NULL;
p->task = task_create(as, "app");
p->task = task_create(as, name);
ASSERT(p->task);
 
/*
106,6 → 107,7
* executable image. The task is returned in *task.
*
* @param image_addr Address of an executable program image.
* @param name Name to set for the program's task.
* @param p Buffer for storing program info. If image_addr
* points to a loader image, p->task will be set to
* NULL and EOK will be returned.
112,7 → 114,7
*
* @return EOK on success or negative error code.
*/
int program_create_from_image(void *image_addr, program_t *p)
int program_create_from_image(void *image_addr, char *name, program_t *p)
{
as_t *as;
unsigned int rc;
131,12 → 133,12
/* Register image as the program loader */
ASSERT(program_loader == NULL);
program_loader = image_addr;
printf("Registered program loader at 0x%" PRIp "\n",
LOG("Registered program loader at 0x%" PRIp "\n",
image_addr);
return EOK;
}
 
program_create(as, ((elf_header_t *) image_addr)->e_entry, p);
program_create(as, ((elf_header_t *) image_addr)->e_entry, name, p);
 
return EOK;
}
143,10 → 145,12
 
/** Create a task from the program loader image.
*
* @param p Buffer for storing program info.
* @param p Buffer for storing program info.
* @param name Name to set for the program's task.
*
* @return EOK on success or negative error code.
*/
int program_create_loader(program_t *p)
int program_create_loader(program_t *p, char *name)
{
as_t *as;
unsigned int rc;
167,7 → 171,8
return ENOENT;
}
 
program_create(as, ((elf_header_t *) program_loader)->e_entry, p);
program_create(as, ((elf_header_t *) program_loader)->e_entry,
name, p);
 
return EOK;
}
185,48 → 190,37
 
/** Syscall for creating a new loader instance from userspace.
*
* Creates a new task from the program loader image, connects a phone
* to it and stores the phone id into the provided buffer.
* Creates a new task from the program loader image and sets
* the task name.
*
* @param uspace_phone_id Userspace address where to store the phone id.
* @param name Name to set on the new task (typically the same
* as the command used to execute it).
*
* @return 0 on success or an error code from @ref errno.h.
*/
unative_t sys_program_spawn_loader(int *uspace_phone_id)
unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len)
{
program_t p;
int fake_id;
int rc;
int phone_id;
char namebuf[TASK_NAME_BUFLEN];
 
fake_id = 0;
/* Cap length of name and copy it from userspace. */
 
/* Before we even try creating the task, see if we can write the id */
rc = (unative_t) copy_to_uspace(uspace_phone_id, &fake_id,
sizeof(fake_id));
if (name_len > TASK_NAME_BUFLEN - 1)
name_len = TASK_NAME_BUFLEN - 1;
 
rc = copy_from_uspace(namebuf, uspace_name, name_len);
if (rc != 0)
return rc;
return (unative_t) rc;
 
phone_id = phone_alloc();
if (phone_id < 0)
return ELIMIT;
namebuf[name_len] = 0;
 
rc = program_create_loader(&p);
/* Spawn the new task. */
 
rc = program_create_loader(&p, namebuf);
if (rc != 0)
return rc;
 
phone_connect(phone_id, &p.task->answerbox);
 
/* No need to aquire lock before task_ready() */
rc = (unative_t) copy_to_uspace(uspace_phone_id, &phone_id,
sizeof(phone_id));
if (rc != 0) {
/* Ooops */
ipc_phone_hangup(&TASK->phones[phone_id]);
task_kill(p.task->taskid);
return rc;
}
 
// FIXME: control the capabilities
cap_set(p.task, cap_get(TASK));
 
/branches/arm/kernel/generic/src/proc/thread.c
102,7 → 102,7
thread_id_t last_tid = 0;
 
static slab_cache_t *thread_slab;
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
slab_cache_t *fpu_context_slab;
#endif
 
161,7 → 161,7
/* call the architecture-specific part of the constructor */
thr_constructor_arch(t);
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
#ifdef CONFIG_FPU_LAZY
t->saved_fpu_context = NULL;
#else
169,11 → 169,11
if (!t->saved_fpu_context)
return -1;
#endif
#endif
#endif
 
t->kstack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | kmflags);
if (!t->kstack) {
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
if (t->saved_fpu_context)
slab_free(fpu_context_slab, t->saved_fpu_context);
#endif
196,7 → 196,7
thr_destructor_arch(t);
 
frame_free(KA2PA(t->kstack));
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
if (t->saved_fpu_context)
slab_free(fpu_context_slab, t->saved_fpu_context);
#endif
211,11 → 211,11
void thread_init(void)
{
THREAD = NULL;
atomic_set(&nrdy,0);
atomic_set(&nrdy, 0);
thread_slab = slab_cache_create("thread_slab", sizeof(thread_t), 0,
thr_constructor, thr_destructor, 0);
 
#ifdef ARCH_HAS_FPU
#ifdef CONFIG_FPU
fpu_context_slab = slab_cache_create("fpu_slab", sizeof(fpu_context_t),
FPU_CONTEXT_ALIGN, NULL, NULL, 0);
#endif
279,7 → 279,7
* guarantee that the task won't cease to exist during the
* call. The task's lock may not be held.
* @param flags Thread flags.
* @param name Symbolic name.
* @param name Symbolic name (a copy is made).
* @param uncounted Thread's accounting doesn't affect accumulated task
* accounting.
*
316,6 → 316,7
interrupts_restore(ipl);
memcpy(t->name, name, THREAD_NAME_BUFLEN);
t->name[THREAD_NAME_BUFLEN - 1] = 0;
t->thread_code = func;
t->thread_arg = arg;
708,7 → 709,7
*
*/
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name,
thread_id_t *uspace_thread_id)
size_t name_len, thread_id_t *uspace_thread_id)
{
thread_t *t;
char namebuf[THREAD_NAME_BUFLEN];
715,10 → 716,15
uspace_arg_t *kernel_uarg;
int rc;
 
rc = copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN);
if (name_len > THREAD_NAME_BUFLEN - 1)
name_len = THREAD_NAME_BUFLEN - 1;
 
rc = copy_from_uspace(namebuf, uspace_name, name_len);
if (rc != 0)
return (unative_t) rc;
 
namebuf[name_len] = 0;
 
/*
* In case of failure, kernel_uarg will be deallocated in this function.
* In case of success, kernel_uarg will be freed in uinit().
757,14 → 763,20
return (unative_t) rc;
}
}
#ifdef CONFIG_UDEBUG
/*
* Generate udebug THREAD_B event and attach the thread.
* This must be done atomically (with the debug locks held),
* otherwise we would either miss some thread or receive
* THREAD_B events for threads that already existed
* and could be detected with THREAD_READ before.
*/
udebug_thread_b_event_attach(t, TASK);
#else
thread_attach(t, TASK);
#endif
thread_ready(t);
 
#ifdef CONFIG_UDEBUG
/* Generate udebug THREAD_B event */
udebug_thread_b_event(t);
#endif
 
return 0;
} else
free(kernel_uarg);
/branches/arm/kernel/generic/src/proc/tasklet.c
51,7 → 51,7
tasklet_list = malloc(sizeof(tasklet_descriptor_t *) * config.cpu_count, 0);
if (!tasklet_list)
panic("Error initializing tasklets");
panic("Error initializing tasklets.");
for (i = 0; i < config.cpu_count; i++)
tasklet_list[i] = NULL;
/branches/arm/kernel/generic/src/lib/string.c
0,0 → 1,712
/*
* Copyright (c) 2001-2004 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 generic
* @{
*/
 
/**
* @file
* @brief String functions.
*
* Strings and characters use the Universal Character Set (UCS). The standard
* strings, called just strings are encoded in UTF-8. Wide strings (encoded
* in UTF-32) are supported to a limited degree. A single character is
* represented as wchar_t.@n
*
* Overview of the terminology:@n
*
* Term Meaning
* -------------------- ----------------------------------------------------
* byte 8 bits stored in uint8_t (unsigned 8 bit integer)
*
* character UTF-32 encoded Unicode character, stored in wchar_t
* (signed 32 bit integer), code points 0 .. 1114111
* are valid
*
* ASCII character 7 bit encoded ASCII character, stored in char
* (usually signed 8 bit integer), code points 0 .. 127
* are valid
*
* string UTF-8 encoded NULL-terminated Unicode string, char *
*
* wide string UTF-32 encoded NULL-terminated Unicode string,
* wchar_t *
*
* [wide] string size number of BYTES in a [wide] string (excluding
* the NULL-terminator), size_t
*
* [wide] string length number of CHARACTERS in a [wide] string (excluding
* the NULL-terminator), size_t
*
* [wide] string width number of display cells on a monospace display taken
* by a [wide] string, size_t
*
*
* Overview of string metrics:@n
*
* Metric Abbrev. Type Meaning
* ------ ------ ------ -------------------------------------------------
* size n size_t number of BYTES in a string (excluding the
* NULL-terminator)
*
* length l size_t number of CHARACTERS in a string (excluding the
* null terminator)
*
* width w size_t number of display cells on a monospace display
* taken by a string
*
*
* Function naming prefixes:@n
*
* chr_ operate on characters
* ascii_ operate on ASCII characters
* str_ operate on strings
* wstr_ operate on wide strings
*
* [w]str_[n|l|w] operate on a prefix limited by size, length
* or width
*
*
* A specific character inside a [wide] string can be referred to by:@n
*
* pointer (char *, wchar_t *)
* byte offset (size_t)
* character index (size_t)
*
*/
 
#include <string.h>
#include <print.h>
#include <cpu.h>
#include <arch/asm.h>
#include <arch.h>
#include <errno.h>
#include <align.h>
#include <debug.h>
 
/** Byte mask consisting of lowest @n bits (out of 8) */
#define LO_MASK_8(n) ((uint8_t) ((1 << (n)) - 1))
 
/** Byte mask consisting of lowest @n bits (out of 32) */
#define LO_MASK_32(n) ((uint32_t) ((1 << (n)) - 1))
 
/** Byte mask consisting of highest @n bits (out of 8) */
#define HI_MASK_8(n) (~LO_MASK_8(8 - (n)))
 
/** Number of data bits in a UTF-8 continuation byte */
#define CONT_BITS 6
 
/** Decode a single character from a string.
*
* Decode a single character from a string of size @a size. Decoding starts
* at @a offset and this offset is moved to the beginning of the next
* character. In case of decoding error, offset generally advances at least
* by one. However, offset is never moved beyond size.
*
* @param str String (not necessarily NULL-terminated).
* @param offset Byte offset in string where to start decoding.
* @param size Size of the string (in bytes).
*
* @return Value of decoded character, U_SPECIAL on decoding error or
* NULL if attempt to decode beyond @a size.
*
*/
wchar_t str_decode(const char *str, size_t *offset, size_t size)
{
if (*offset + 1 > size)
return 0;
/* First byte read from string */
uint8_t b0 = (uint8_t) str[(*offset)++];
/* Determine code length */
unsigned int b0_bits; /* Data bits in first byte */
unsigned int cbytes; /* Number of continuation bytes */
if ((b0 & 0x80) == 0) {
/* 0xxxxxxx (Plain ASCII) */
b0_bits = 7;
cbytes = 0;
} else if ((b0 & 0xe0) == 0xc0) {
/* 110xxxxx 10xxxxxx */
b0_bits = 5;
cbytes = 1;
} else if ((b0 & 0xf0) == 0xe0) {
/* 1110xxxx 10xxxxxx 10xxxxxx */
b0_bits = 4;
cbytes = 2;
} else if ((b0 & 0xf8) == 0xf0) {
/* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
b0_bits = 3;
cbytes = 3;
} else {
/* 10xxxxxx -- unexpected continuation byte */
return U_SPECIAL;
}
if (*offset + cbytes > size)
return U_SPECIAL;
wchar_t ch = b0 & LO_MASK_8(b0_bits);
/* Decode continuation bytes */
while (cbytes > 0) {
uint8_t b = (uint8_t) str[(*offset)++];
/* Must be 10xxxxxx */
if ((b & 0xc0) != 0x80)
return U_SPECIAL;
/* Shift data bits to ch */
ch = (ch << CONT_BITS) | (wchar_t) (b & LO_MASK_8(CONT_BITS));
cbytes--;
}
return ch;
}
 
/** Encode a single character to string representation.
*
* Encode a single character to string representation (i.e. UTF-8) and store
* it into a buffer at @a offset. Encoding starts at @a offset and this offset
* is moved to the position where the next character can be written to.
*
* @param ch Input character.
* @param str Output buffer.
* @param offset Byte offset where to start writing.
* @param size Size of the output buffer (in bytes).
*
* @return EOK if the character was encoded successfully, EOVERFLOW if there
* was not enough space in the output buffer or EINVAL if the character
* code was invalid.
*/
int chr_encode(wchar_t ch, char *str, size_t *offset, size_t size)
{
if (*offset >= size)
return EOVERFLOW;
if (!chr_check(ch))
return EINVAL;
/* Unsigned version of ch (bit operations should only be done
on unsigned types). */
uint32_t cc = (uint32_t) ch;
/* Determine how many continuation bytes are needed */
unsigned int b0_bits; /* Data bits in first byte */
unsigned int cbytes; /* Number of continuation bytes */
if ((cc & ~LO_MASK_32(7)) == 0) {
b0_bits = 7;
cbytes = 0;
} else if ((cc & ~LO_MASK_32(11)) == 0) {
b0_bits = 5;
cbytes = 1;
} else if ((cc & ~LO_MASK_32(16)) == 0) {
b0_bits = 4;
cbytes = 2;
} else if ((cc & ~LO_MASK_32(21)) == 0) {
b0_bits = 3;
cbytes = 3;
} else {
/* Codes longer than 21 bits are not supported */
return EINVAL;
}
/* Check for available space in buffer */
if (*offset + cbytes >= size)
return EOVERFLOW;
/* Encode continuation bytes */
unsigned int i;
for (i = cbytes; i > 0; i--) {
str[*offset + i] = 0x80 | (cc & LO_MASK_32(CONT_BITS));
cc = cc >> CONT_BITS;
}
/* Encode first byte */
str[*offset] = (cc & LO_MASK_32(b0_bits)) | HI_MASK_8(8 - b0_bits - 1);
/* Advance offset */
*offset += cbytes + 1;
return EOK;
}
 
/** Get size of string.
*
* Get the number of bytes which are used by the string @a str (excluding the
* NULL-terminator).
*
* @param str String to consider.
*
* @return Number of bytes used by the string
*
*/
size_t str_size(const char *str)
{
size_t size = 0;
while (*str++ != 0)
size++;
return size;
}
 
/** Get size of wide string.
*
* Get the number of bytes which are used by the wide string @a str (excluding the
* NULL-terminator).
*
* @param str Wide string to consider.
*
* @return Number of bytes used by the wide string
*
*/
size_t wstr_size(const wchar_t *str)
{
return (wstr_length(str) * sizeof(wchar_t));
}
 
/** Get size of string with length limit.
*
* Get the number of bytes which are used by up to @a max_len first
* characters in the string @a str. If @a max_len is greater than
* the length of @a str, the entire string is measured (excluding the
* NULL-terminator).
*
* @param str String to consider.
* @param max_len Maximum number of characters to measure.
*
* @return Number of bytes used by the characters.
*
*/
size_t str_lsize(const char *str, size_t max_len)
{
size_t len = 0;
size_t offset = 0;
while (len < max_len) {
if (str_decode(str, &offset, STR_NO_LIMIT) == 0)
break;
len++;
}
return offset;
}
 
/** Get size of wide string with length limit.
*
* Get the number of bytes which are used by up to @a max_len first
* wide characters in the wide string @a str. If @a max_len is greater than
* the length of @a str, the entire wide string is measured (excluding the
* NULL-terminator).
*
* @param str Wide string to consider.
* @param max_len Maximum number of wide characters to measure.
*
* @return Number of bytes used by the wide characters.
*
*/
size_t wstr_lsize(const wchar_t *str, size_t max_len)
{
return (wstr_nlength(str, max_len * sizeof(wchar_t)) * sizeof(wchar_t));
}
 
/** Get number of characters in a string.
*
* @param str NULL-terminated string.
*
* @return Number of characters in string.
*
*/
size_t str_length(const char *str)
{
size_t len = 0;
size_t offset = 0;
while (str_decode(str, &offset, STR_NO_LIMIT) != 0)
len++;
return len;
}
 
/** Get number of characters in a wide string.
*
* @param str NULL-terminated wide string.
*
* @return Number of characters in @a str.
*
*/
size_t wstr_length(const wchar_t *wstr)
{
size_t len = 0;
while (*wstr++ != 0)
len++;
return len;
}
 
/** Get number of characters in a string with size limit.
*
* @param str NULL-terminated string.
* @param size Maximum number of bytes to consider.
*
* @return Number of characters in string.
*
*/
size_t str_nlength(const char *str, size_t size)
{
size_t len = 0;
size_t offset = 0;
while (str_decode(str, &offset, size) != 0)
len++;
return len;
}
 
/** Get number of characters in a string with size limit.
*
* @param str NULL-terminated string.
* @param size Maximum number of bytes to consider.
*
* @return Number of characters in string.
*
*/
size_t wstr_nlength(const wchar_t *str, size_t size)
{
size_t len = 0;
size_t limit = ALIGN_DOWN(size, sizeof(wchar_t));
size_t offset = 0;
while ((offset < limit) && (*str++ != 0)) {
len++;
offset += sizeof(wchar_t);
}
return len;
}
 
/** Check whether character is plain ASCII.
*
* @return True if character is plain ASCII.
*
*/
bool ascii_check(wchar_t ch)
{
if ((ch >= 0) && (ch <= 127))
return true;
return false;
}
 
/** Check whether character is valid
*
* @return True if character is a valid Unicode code point.
*
*/
bool chr_check(wchar_t ch)
{
if ((ch >= 0) && (ch <= 1114111))
return true;
return false;
}
 
/** Compare two NULL terminated strings.
*
* Do a char-by-char comparison of two NULL-terminated strings.
* The strings are considered equal iff they consist of the same
* characters on the minimum of their lengths.
*
* @param s1 First string to compare.
* @param s2 Second string to compare.
*
* @return 0 if the strings are equal, -1 if first is smaller,
* 1 if second smaller.
*
*/
int str_cmp(const char *s1, const char *s2)
{
wchar_t c1 = 0;
wchar_t c2 = 0;
size_t off1 = 0;
size_t off2 = 0;
 
while (true) {
c1 = str_decode(s1, &off1, STR_NO_LIMIT);
c2 = str_decode(s2, &off2, STR_NO_LIMIT);
 
if (c1 < c2)
return -1;
if (c1 > c2)
return 1;
 
if (c1 == 0 || c2 == 0)
break;
}
 
return 0;
}
 
/** Compare two NULL terminated strings with length limit.
*
* Do a char-by-char comparison of two NULL-terminated strings.
* The strings are considered equal iff they consist of the same
* characters on the minimum of their lengths and the length limit.
*
* @param s1 First string to compare.
* @param s2 Second string to compare.
* @param max_len Maximum number of characters to consider.
*
* @return 0 if the strings are equal, -1 if first is smaller,
* 1 if second smaller.
*
*/
int str_lcmp(const char *s1, const char *s2, size_t max_len)
{
wchar_t c1 = 0;
wchar_t c2 = 0;
size_t off1 = 0;
size_t off2 = 0;
size_t len = 0;
 
while (true) {
if (len >= max_len)
break;
 
c1 = str_decode(s1, &off1, STR_NO_LIMIT);
c2 = str_decode(s2, &off2, STR_NO_LIMIT);
 
if (c1 < c2)
return -1;
 
if (c1 > c2)
return 1;
 
if (c1 == 0 || c2 == 0)
break;
 
++len;
}
 
return 0;
 
}
 
/** Copy string.
*
* Copy source string @a src to destination buffer @a dest.
* No more than @a size bytes are written. If the size of the output buffer
* is at least one byte, the output string will always be well-formed, i.e.
* null-terminated and containing only complete characters.
*
* @param dst Destination buffer.
* @param count Size of the destination buffer (must be > 0).
* @param src Source string.
*/
void str_cpy(char *dest, size_t size, const char *src)
{
wchar_t ch;
size_t src_off;
size_t dest_off;
 
/* There must be space for a null terminator in the buffer. */
ASSERT(size > 0);
src_off = 0;
dest_off = 0;
 
while ((ch = str_decode(src, &src_off, STR_NO_LIMIT)) != 0) {
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
break;
}
 
dest[dest_off] = '\0';
}
 
/** Copy size-limited substring.
*
* Copy prefix of string @a src of max. size @a size to destination buffer
* @a dest. No more than @a size bytes are written. The output string will
* always be well-formed, i.e. null-terminated and containing only complete
* characters.
*
* No more than @a n bytes are read from the input string, so it does not
* have to be null-terminated.
*
* @param dst Destination buffer.
* @param count Size of the destination buffer (must be > 0).
* @param src Source string.
* @param n Maximum number of bytes to read from @a src.
*/
void str_ncpy(char *dest, size_t size, const char *src, size_t n)
{
wchar_t ch;
size_t src_off;
size_t dest_off;
 
/* There must be space for a null terminator in the buffer. */
ASSERT(size > 0);
src_off = 0;
dest_off = 0;
 
while ((ch = str_decode(src, &src_off, n)) != 0) {
if (chr_encode(ch, dest, &dest_off, size - 1) != EOK)
break;
}
 
dest[dest_off] = '\0';
}
 
/** Copy NULL-terminated wide string to string
*
* Copy source wide string @a src to destination buffer @a dst.
* No more than @a size bytes are written. NULL-terminator is always
* written after the last succesfully copied character (i.e. if the
* destination buffer is has at least 1 byte, it will be always
* NULL-terminated).
*
* @param src Source wide string.
* @param dst Destination buffer.
* @param count Size of the destination buffer.
*
*/
void wstr_nstr(char *dst, const wchar_t *src, size_t size)
{
/* No space for the NULL-terminator in the buffer */
if (size == 0)
return;
wchar_t ch;
size_t src_idx = 0;
size_t dst_off = 0;
while ((ch = src[src_idx++]) != 0) {
if (chr_encode(ch, dst, &dst_off, size) != EOK)
break;
}
if (dst_off >= size)
dst[size - 1] = 0;
else
dst[dst_off] = 0;
}
 
/** Find first occurence of character in string.
*
* @param str String to search.
* @param ch Character to look for.
*
* @return Pointer to character in @a str or NULL if not found.
*
*/
const char *str_chr(const char *str, wchar_t ch)
{
wchar_t acc;
size_t off = 0;
size_t last = 0;
while ((acc = str_decode(str, &off, STR_NO_LIMIT)) != 0) {
if (acc == ch)
return (str + last);
last = off;
}
return NULL;
}
 
/** Insert a wide character into a wide string.
*
* Insert a wide character into a wide string at position
* @a pos. The characters after the position are shifted.
*
* @param str String to insert to.
* @param ch Character to insert to.
* @param pos Character index where to insert.
@ @param max_pos Characters in the buffer.
*
* @return True if the insertion was sucessful, false if the position
* is out of bounds.
*
*/
bool wstr_linsert(wchar_t *str, wchar_t ch, size_t pos, size_t max_pos)
{
size_t len = wstr_length(str);
if ((pos > len) || (pos + 1 > max_pos))
return false;
size_t i;
for (i = len; i + 1 > pos; i--)
str[i + 1] = str[i];
str[pos] = ch;
return true;
}
 
/** Remove a wide character from a wide string.
*
* Remove a wide character from a wide string at position
* @a pos. The characters after the position are shifted.
*
* @param str String to remove from.
* @param pos Character index to remove.
*
* @return True if the removal was sucessful, false if the position
* is out of bounds.
*
*/
bool wstr_remove(wchar_t *str, size_t pos)
{
size_t len = wstr_length(str);
if (pos >= len)
return false;
size_t i;
for (i = pos + 1; i <= len; i++)
str[i - 1] = str[i];
return true;
}
 
/** @}
*/
/branches/arm/kernel/generic/src/lib/sort.c
45,8 → 45,8
 
#define EBUFSIZE 32
 
void _qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot);
void _bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot);
void _qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot);
void _bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot);
 
/** Quicksort wrapper
*
61,7 → 61,7
* @param cmp Comparator function.
*
*/
void qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b))
void qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b))
{
uint8_t buf_tmp[EBUFSIZE];
uint8_t buf_pivot[EBUFSIZE];
93,7 → 93,7
* @param pivot Pointer to scratch memory buffer e_size bytes long.
*
*/
void _qsort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot)
void _qsort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *tmp, void *pivot)
{
if (n > 4) {
unsigned int i = 0, j = n - 1;
133,7 → 133,7
* @param cmp Comparator function.
*
*/
void bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b))
void bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b))
{
uint8_t buf_slot[EBUFSIZE];
void * slot = buf_slot;
160,7 → 160,7
* @param slot Pointer to scratch memory buffer e_size bytes long.
*
*/
void _bubblesort(void * data, count_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot)
void _bubblesort(void * data, size_t n, size_t e_size, int (* cmp) (void * a, void * b), void *slot)
{
bool done = false;
void * p;
/branches/arm/kernel/generic/src/lib/func.c
47,7 → 47,7
 
/** Halt wrapper
*
* Set halt flag and halt the cpu.
* Set halt flag and halt the CPU.
*
*/
void halt()
54,9 → 54,7
{
#ifdef CONFIG_DEBUG
bool rundebugger = false;
 
// TODO test_and_set not defined on all arches
// if (!test_and_set(&haltstate))
if (!atomic_get(&haltstate)) {
atomic_set(&haltstate, 1);
rundebugger = true;
64,118 → 62,22
#else
atomic_set(&haltstate, 1);
#endif
 
interrupts_disable();
#ifdef CONFIG_DEBUG
if (rundebugger) {
printf("\n");
kconsole("panic"); /* Run kconsole as a last resort to user */
}
#endif
#if (defined(CONFIG_DEBUG)) && (defined(CONFIG_KCONSOLE))
if ((rundebugger) && (kconsole_check_poll()))
kconsole("panic", "\nLast resort kernel console ready.\n", false);
#endif
if (CPU)
printf("cpu%u: halted\n", CPU->id);
else
printf("cpu: halted\n");
cpu_halt();
}
 
/** Return number of characters in a string.
*
* @param str NULL terminated string.
*
* @return Number of characters in str.
*/
size_t strlen(const char *str)
{
int i;
for (i = 0; str[i]; i++)
;
return i;
}
 
/** Compare two NULL terminated strings
*
* Do a char-by-char comparison of two NULL terminated strings.
* The strings are considered equal iff they consist of the same
* characters on the minimum of their lengths.
*
* @param src First string to compare.
* @param dst Second string to compare.
*
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller.
*
*/
int strcmp(const char *src, const char *dst)
{
for (; *src && *dst; src++, dst++) {
if (*src < *dst)
return -1;
if (*src > *dst)
return 1;
}
if (*src == *dst)
return 0;
if (!*src)
return -1;
return 1;
}
 
 
/** Compare two NULL terminated strings
*
* Do a char-by-char comparison of two NULL terminated strings.
* The strings are considered equal iff they consist of the same
* characters on the minimum of their lengths and specified maximal
* length.
*
* @param src First string to compare.
* @param dst Second string to compare.
* @param len Maximal length for comparison.
*
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller.
*
*/
int strncmp(const char *src, const char *dst, size_t len)
{
unsigned int i;
for (i = 0; (*src) && (*dst) && (i < len); src++, dst++, i++) {
if (*src < *dst)
return -1;
if (*src > *dst)
return 1;
}
if (i == len || *src == *dst)
return 0;
if (!*src)
return -1;
return 1;
}
 
 
 
/** Copy NULL terminated string.
*
* Copy at most 'len' characters from string 'src' to 'dest'.
* If 'src' is shorter than 'len', '\0' is inserted behind the
* last copied character.
*
* @param src Source string.
* @param dest Destination buffer.
* @param len Size of destination buffer.
*/
void strncpy(char *dest, const char *src, size_t len)
{
unsigned int i;
for (i = 0; i < len; i++) {
if (!(dest[i] = src[i]))
return;
}
dest[i-1] = '\0';
}
 
/** Convert ascii representation to unative_t
*
* Supports 0x for hexa & 0 for octal notation.
/branches/arm/kernel/generic/src/lib/memstr.c
1,5 → 1,6
/*
* Copyright (c) 2001-2004 Jakub Jermar
* Copyright (c) 2008 Jiri Svoboda
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
76,6 → 77,51
return (char *) dst;
}
 
/** Move memory block with possible overlapping.
*
* Copy cnt bytes from src address to dst address. The source and destination
* memory areas may overlap.
*
* @param src Source address to copy from.
* @param dst Destination address to copy to.
* @param cnt Number of bytes to copy.
*
* @return Destination address.
*/
void *memmove(void *dst, const void *src, size_t n)
{
const uint8_t *sp;
uint8_t *dp;
 
/* Nothing to do? */
if (src == dst)
return dst;
 
/* Non-overlapping? */
if (dst >= src + n || src >= dst + n) {
return memcpy(dst, src, n);
}
 
/* Which direction? */
if (src > dst) {
/* Forwards. */
sp = src;
dp = dst;
 
while (n-- != 0)
*dp++ = *sp++;
} else {
/* Backwards. */
sp = src + (n - 1);
dp = dst + (n - 1);
 
while (n-- != 0)
*dp-- = *sp--;
}
 
return dst;
}
 
/** Fill block of memory
*
* Fill cnt bytes at dst address with the value x. The filling is done
114,25 → 160,5
p[i] = x;
}
 
/** Copy string.
*
* Copy string from src address to dst address. The copying is done
* char-by-char until the null character. The source and destination memory
* areas cannot overlap.
*
* @param src Source string to copy from.
* @param dst Destination string to copy to.
*
* @return Address of the destination string.
*/
char *strcpy(char *dest, const char *src)
{
char *orig = dest;
while ((*(dest++) = *(src++)))
;
return orig;
}
 
/** @}
*/
/branches/arm/kernel/generic/src/lib/rd.c
88,9 → 88,7
rd_parea.pbase = ALIGN_DOWN((uintptr_t) KA2PA((void *) header + hsize),
FRAME_SIZE);
rd_parea.vbase = (uintptr_t) ((void *) header + hsize);
rd_parea.frames = SIZE2FRAMES(dsize);
rd_parea.cacheable = true;
ddi_parea_register(&rd_parea);
 
sysinfo_set_item_val("rd", NULL, true);
/branches/arm/kernel/generic/src/adt/btree.c
63,9 → 63,9
static void node_remove_key_and_rsubtree(btree_node_t *node, btree_key_t key);
static btree_node_t *node_split(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree, btree_key_t *median);
static btree_node_t *node_combine(btree_node_t *node);
static index_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right);
static void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, index_t idx);
static void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, index_t idx);
static size_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right);
static void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, size_t idx);
static void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, size_t idx);
static bool try_insert_by_rotation_to_left(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
static bool try_insert_by_rotation_to_right(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree);
static bool try_rotation_from_left(btree_node_t *rnode);
124,7 → 124,7
lnode = leaf_node;
if (!lnode) {
if (btree_search(t, key, &lnode)) {
panic("B-tree %p already contains key %" PRIu64 "\n", t, key);
panic("B-tree %p already contains key %" PRIu64 ".", t, key);
}
}
137,7 → 137,7
*/
void btree_destroy_subtree(btree_node_t *root)
{
count_t i;
size_t i;
 
if (root->keys) {
for (i = 0; i < root->keys + 1; i++) {
224,7 → 224,7
lnode = leaf_node;
if (!lnode) {
if (!btree_search(t, key, &lnode)) {
panic("B-tree %p does not contain key %" PRIu64 "\n", t, key);
panic("B-tree %p does not contain key %" PRIu64 ".", t, key);
}
}
269,7 → 269,7
}
if (node->keys > FILL_FACTOR) {
count_t i;
size_t i;
 
/*
* The key can be immediatelly removed.
285,7 → 285,7
}
} else {
index_t idx;
size_t idx;
btree_node_t *rnode, *parent;
 
/*
335,7 → 335,7
continue;
} else {
void *val;
count_t i;
size_t i;
/*
* Now if the key is smaller than cur->key[i]
442,11 → 442,11
*/
void node_insert_key_and_lsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *lsubtree)
{
count_t i;
size_t i;
 
for (i = 0; i < node->keys; i++) {
if (key < node->key[i]) {
count_t j;
size_t j;
for (j = node->keys; j > i; j--) {
node->key[j] = node->key[j - 1];
478,11 → 478,11
*/
void node_insert_key_and_rsubtree(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree)
{
count_t i;
size_t i;
 
for (i = 0; i < node->keys; i++) {
if (key < node->key[i]) {
count_t j;
size_t j;
for (j = node->keys; j > i; j--) {
node->key[j] = node->key[j - 1];
510,7 → 510,7
*/
void node_remove_key_and_lsubtree(btree_node_t *node, btree_key_t key)
{
count_t i, j;
size_t i, j;
for (i = 0; i < node->keys; i++) {
if (key == node->key[i]) {
524,7 → 524,7
return;
}
}
panic("node %p does not contain key %" PRIu64 "\n", node, key);
panic("Node %p does not contain key %" PRIu64 ".", node, key);
}
 
/** Remove key and its right subtree pointer from B-tree node.
538,7 → 538,7
*/
void node_remove_key_and_rsubtree(btree_node_t *node, btree_key_t key)
{
count_t i, j;
size_t i, j;
for (i = 0; i < node->keys; i++) {
if (key == node->key[i]) {
551,7 → 551,7
return;
}
}
panic("node %p does not contain key %" PRIu64 "\n", node, key);
panic("Node %p does not contain key %" PRIu64 ".", node, key);
}
 
/** Split full B-tree node and insert new key-value-right-subtree triplet.
576,7 → 576,7
btree_node_t *node_split(btree_node_t *node, btree_key_t key, void *value, btree_node_t *rsubtree, btree_key_t *median)
{
btree_node_t *rnode;
count_t i, j;
size_t i, j;
 
ASSERT(median);
ASSERT(node->keys == BTREE_MAX_KEYS);
603,7 → 603,7
* Copy big keys, values and subtree pointers to the new right sibling.
* If this is an index node, do not copy the median.
*/
i = (count_t) INDEX_NODE(node);
i = (size_t) INDEX_NODE(node);
for (i += MEDIAN_HIGH_INDEX(node), j = 0; i < node->keys; i++, j++) {
rnode->key[j] = node->key[i];
rnode->value[j] = node->value[i];
636,9 → 636,9
*/
btree_node_t *node_combine(btree_node_t *node)
{
index_t idx;
size_t idx;
btree_node_t *rnode;
count_t i;
size_t i;
 
ASSERT(!ROOT_NODE(node));
685,15 → 685,15
*
* @return Index of the key associated with the subtree.
*/
index_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right)
size_t find_key_by_subtree(btree_node_t *node, btree_node_t *subtree, bool right)
{
count_t i;
size_t i;
for (i = 0; i < node->keys + 1; i++) {
if (subtree == node->subtree[i])
return i - (int) (right != false);
}
panic("node %p does not contain subtree %p\n", node, subtree);
panic("Node %p does not contain subtree %p.", node, subtree);
}
 
/** Rotate one key-value-rsubtree triplet from the left sibling to the right sibling.
706,7 → 706,7
* @param rnode Right sibling.
* @param idx Index of the parent node key that is taking part in the rotation.
*/
void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, index_t idx)
void rotate_from_left(btree_node_t *lnode, btree_node_t *rnode, size_t idx)
{
btree_key_t key;
 
743,7 → 743,7
* @param rnode Right sibling.
* @param idx Index of the parent node key that is taking part in the rotation.
*/
void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, index_t idx)
void rotate_from_right(btree_node_t *lnode, btree_node_t *rnode, size_t idx)
{
btree_key_t key;
 
786,7 → 786,7
*/
bool try_insert_by_rotation_to_left(btree_node_t *node, btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
{
index_t idx;
size_t idx;
btree_node_t *lnode;
 
/*
833,7 → 833,7
*/
bool try_insert_by_rotation_to_right(btree_node_t *node, btree_key_t inskey, void *insvalue, btree_node_t *rsubtree)
{
index_t idx;
size_t idx;
btree_node_t *rnode;
 
/*
872,7 → 872,7
*/
bool try_rotation_from_left(btree_node_t *rnode)
{
index_t idx;
size_t idx;
btree_node_t *lnode;
 
/*
907,7 → 907,7
*/
bool try_rotation_from_right(btree_node_t *lnode)
{
index_t idx;
size_t idx;
btree_node_t *rnode;
 
/*
940,7 → 940,7
*/
void btree_print(btree_t *t)
{
count_t i;
size_t i;
int depth = t->root->depth;
link_t head, *cur;
 
/branches/arm/kernel/generic/src/adt/hash_table.c
32,7 → 32,7
 
/**
* @file
* @brief Implementation of generic chained hash table.
* @brief Implementation of generic chained hash table.
*
* This file contains implementation of generic chained hash table.
*/
51,18 → 51,20
* @param max_keys Maximal number of keys needed to identify an item.
* @param op Hash table operations structure.
*/
void hash_table_create(hash_table_t *h, count_t m, count_t max_keys, hash_table_operations_t *op)
void hash_table_create(hash_table_t *h, size_t m, size_t max_keys, hash_table_operations_t *op)
{
index_t i;
size_t i;
 
ASSERT(h);
ASSERT(op && op->hash && op->compare);
ASSERT(op);
ASSERT(op->hash);
ASSERT(op->compare);
ASSERT(max_keys > 0);
h->entry = (link_t *) malloc(m * sizeof(link_t), 0);
if (!h->entry) {
panic("cannot allocate memory for hash table\n");
}
if (!h->entry)
panic("Cannot allocate memory for hash table.");
memsetb(h->entry, m * sizeof(link_t), 0);
for (i = 0; i < m; i++)
81,11 → 83,14
*/
void hash_table_insert(hash_table_t *h, unative_t key[], link_t *item)
{
index_t chain;
 
size_t chain;
ASSERT(item);
ASSERT(h && h->op && h->op->hash && h->op->compare);
 
ASSERT(h);
ASSERT(h->op);
ASSERT(h->op->hash);
ASSERT(h->op->compare);
chain = h->op->hash(key);
ASSERT(chain < h->entries);
102,10 → 107,13
link_t *hash_table_find(hash_table_t *h, unative_t key[])
{
link_t *cur;
index_t chain;
 
ASSERT(h && h->op && h->op->hash && h->op->compare);
 
size_t chain;
ASSERT(h);
ASSERT(h->op);
ASSERT(h->op->hash);
ASSERT(h->op->compare);
chain = h->op->hash(key);
ASSERT(chain < h->entries);
123,22 → 131,25
 
/** Remove all matching items from hash table.
*
* For each removed item, h->remove_callback() is called.
* For each removed item, h->remove_callback() is called (if not NULL).
*
* @param h Hash table.
* @param key Array of keys that will be compared against items of the hash table.
* @param keys Number of keys in the key array.
*/
void hash_table_remove(hash_table_t *h, unative_t key[], count_t keys)
void hash_table_remove(hash_table_t *h, unative_t key[], size_t keys)
{
index_t chain;
size_t chain;
link_t *cur;
 
ASSERT(h && h->op && h->op->hash && h->op->compare && h->op->remove_callback);
ASSERT(h);
ASSERT(h->op);
ASSERT(h->op->hash);
ASSERT(h->op->compare);
ASSERT(keys <= h->max_keys);
if (keys == h->max_keys) {
 
/*
* All keys are known, hash_table_find() can be used to find the entry.
*/
146,7 → 157,8
cur = hash_table_find(h, key);
if (cur) {
list_remove(cur);
h->op->remove_callback(cur);
if (h->op->remove_callback)
h->op->remove_callback(cur);
}
return;
}
164,7 → 176,8
cur = cur->prev;
list_remove(hlp);
h->op->remove_callback(hlp);
if (h->op->remove_callback)
h->op->remove_callback(hlp);
continue;
}
/branches/arm/kernel/generic/src/adt/bitmap.c
54,7 → 54,7
* @param map Address of the memory used to hold the map.
* @param bits Number of bits stored in bitmap.
*/
void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, count_t bits)
void bitmap_initialize(bitmap_t *bitmap, uint8_t *map, size_t bits)
{
bitmap->map = map;
bitmap->bits = bits;
66,13 → 66,13
* @param start Starting bit.
* @param bits Number of bits to set.
*/
void bitmap_set_range(bitmap_t *bitmap, index_t start, count_t bits)
void bitmap_set_range(bitmap_t *bitmap, size_t start, size_t bits)
{
index_t i=0;
index_t aligned_start;
count_t lub; /* leading unaligned bits */
count_t amb; /* aligned middle bits */
count_t tab; /* trailing aligned bits */
size_t i = 0;
size_t aligned_start;
size_t lub; /* leading unaligned bits */
size_t amb; /* aligned middle bits */
size_t tab; /* trailing aligned bits */
ASSERT(start + bits <= bitmap->bits);
116,13 → 116,13
* @param start Starting bit.
* @param bits Number of bits to clear.
*/
void bitmap_clear_range(bitmap_t *bitmap, index_t start, count_t bits)
void bitmap_clear_range(bitmap_t *bitmap, size_t start, size_t bits)
{
index_t i=0;
index_t aligned_start;
count_t lub; /* leading unaligned bits */
count_t amb; /* aligned middle bits */
count_t tab; /* trailing aligned bits */
size_t i = 0;
size_t aligned_start;
size_t lub; /* leading unaligned bits */
size_t amb; /* aligned middle bits */
size_t tab; /* trailing aligned bits */
ASSERT(start + bits <= bitmap->bits);
168,9 → 168,9
* @param src Source bitmap.
* @param bits Number of bits to copy.
*/
void bitmap_copy(bitmap_t *dst, bitmap_t *src, count_t bits)
void bitmap_copy(bitmap_t *dst, bitmap_t *src, size_t bits)
{
index_t i;
size_t i;
ASSERT(bits <= dst->bits);
ASSERT(bits <= src->bits);
/branches/arm/kernel/generic/src/adt/avl.c
43,7 → 43,7
*
* Every node has a pointer to its parent which allows insertion of multiple
* identical keys into the tree.
*
*
* Be careful when using this tree because of the base atribute which is added
* to every inserted node key. There is no rule in which order nodes with the
* same key are visited.
/branches/arm/kernel/generic/src/mm/slab.c
129,7 → 129,7
static slab_cache_t *slab_extern_cache;
/** Caches for malloc */
static slab_cache_t *malloc_caches[SLAB_MAX_MALLOC_W - SLAB_MIN_MALLOC_W + 1];
char *malloc_names[] = {
static char *malloc_names[] = {
"malloc-16",
"malloc-32",
"malloc-64",
144,7 → 144,11
"malloc-32K",
"malloc-64K",
"malloc-128K",
"malloc-256K"
"malloc-256K",
"malloc-512K",
"malloc-1M",
"malloc-2M",
"malloc-4M"
};
 
/** Slab descriptor */
152,8 → 156,8
slab_cache_t *cache; /**< Pointer to parent cache. */
link_t link; /**< List of full/partial slabs. */
void *start; /**< Start address of first available item. */
count_t available; /**< Count of available items in this slab. */
index_t nextavail; /**< The index of next available item. */
size_t available; /**< Count of available items in this slab. */
size_t nextavail; /**< The index of next available item. */
} slab_t;
 
#ifdef CONFIG_DEBUG
173,7 → 177,7
slab_t *slab;
size_t fsize;
unsigned int i;
unsigned int zone = 0;
size_t zone = 0;
data = frame_alloc_generic(cache->order, FRAME_KA | flags, &zone);
if (!data) {
211,7 → 215,7
*
* @return number of freed frames
*/
static count_t slab_space_free(slab_cache_t *cache, slab_t *slab)
static size_t slab_space_free(slab_cache_t *cache, slab_t *slab)
{
frame_free(KA2PA(slab->start));
if (! (cache->flags & SLAB_CACHE_SLINSIDE))
239,7 → 243,7
*
* @return Number of freed pages
*/
static count_t slab_obj_destroy(slab_cache_t *cache, void *obj, slab_t *slab)
static size_t slab_obj_destroy(slab_cache_t *cache, void *obj, slab_t *slab)
{
int freed = 0;
 
367,10 → 371,10
*
* @return Number of freed pages
*/
static count_t magazine_destroy(slab_cache_t *cache, slab_magazine_t *mag)
static size_t magazine_destroy(slab_cache_t *cache, slab_magazine_t *mag)
{
unsigned int i;
count_t frames = 0;
size_t frames = 0;
 
for (i = 0; i < mag->busy; i++) {
frames += slab_obj_destroy(cache, mag->objs[i], NULL);
645,11 → 649,11
* @param flags If contains SLAB_RECLAIM_ALL, do aggressive freeing
* @return Number of freed pages
*/
static count_t _slab_reclaim(slab_cache_t *cache, int flags)
static size_t _slab_reclaim(slab_cache_t *cache, int flags)
{
unsigned int i;
slab_magazine_t *mag;
count_t frames = 0;
size_t frames = 0;
int magcount;
if (cache->flags & SLAB_CACHE_NOMAGAZINE)
767,11 → 771,11
}
 
/* Go through all caches and reclaim what is possible */
count_t slab_reclaim(int flags)
size_t slab_reclaim(int flags)
{
slab_cache_t *cache;
link_t *cur;
count_t frames = 0;
size_t frames = 0;
 
spinlock_lock(&slab_cache_lock);
 
932,7 → 936,7
void *malloc(unsigned int size, int flags)
{
ASSERT(_slab_initialized);
ASSERT(size && size <= (1 << SLAB_MAX_MALLOC_W));
ASSERT(size <= (1 << SLAB_MAX_MALLOC_W));
if (size < (1 << SLAB_MIN_MALLOC_W))
size = (1 << SLAB_MIN_MALLOC_W);
/branches/arm/kernel/generic/src/mm/tlb.c
79,7 → 79,7
* @param count Number of pages, if required by type.
*/
void tlb_shootdown_start(tlb_invalidate_type_t type, asid_t asid,
uintptr_t page, count_t count)
uintptr_t page, size_t count)
{
unsigned int i;
 
108,7 → 108,7
/*
* Enqueue the message.
*/
index_t idx = cpu->tlb_messages_count++;
size_t idx = cpu->tlb_messages_count++;
cpu->tlb_messages[idx].type = type;
cpu->tlb_messages[idx].asid = asid;
cpu->tlb_messages[idx].page = page;
143,7 → 143,7
tlb_invalidate_type_t type;
asid_t asid;
uintptr_t page;
count_t count;
size_t count;
unsigned int i;
ASSERT(CPU);
173,7 → 173,7
tlb_invalidate_pages(asid, page, count);
break;
default:
panic("unknown type (%d)\n", type);
panic("Unknown type (%d).", type);
break;
}
if (type == TLB_INVL_ALL)
/branches/arm/kernel/generic/src/mm/backend_anon.c
152,7 → 152,7
*/
page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
panic("Could not insert used space.\n");
panic("Cannot insert used space.");
return AS_PF_OK;
}
195,7 → 195,7
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t base = node->key[i];
count_t count = (count_t) node->value[i];
size_t count = (size_t) node->value[i];
unsigned int j;
for (j = 0; j < count; j++) {
/branches/arm/kernel/generic/src/mm/as.c
122,7 → 122,7
int rc;
 
link_initialize(&as->inactive_as_with_asid_link);
mutex_initialize(&as->lock, MUTEX_PASSIVE);
mutex_initialize(&as->lock, MUTEX_PASSIVE);
rc = as_constructor_arch(as, flags);
146,8 → 146,12
AS_KERNEL = as_create(FLAG_AS_KERNEL);
if (!AS_KERNEL)
panic("can't create kernel address space\n");
panic("Cannot create kernel address space.");
/* Make sure the kernel address space
* reference count never drops to zero.
*/
atomic_set(&AS_KERNEL->refcount, 1);
}
 
/** Create address space.
176,7 → 180,7
#else
page_table_create(flags);
#endif
 
return as;
}
 
414,8 → 418,8
btree_node_t, leaf_link);
if ((cond = (bool) node->keys)) {
uintptr_t b = node->key[node->keys - 1];
count_t c =
(count_t) node->value[node->keys - 1];
size_t c =
(size_t) node->value[node->keys - 1];
unsigned int i = 0;
if (overlaps(b, c * PAGE_SIZE, area->base,
440,8 → 444,8
i = (start_free - b) >> PAGE_WIDTH;
if (!used_space_remove(area, start_free,
c - i))
panic("Could not remove used "
"space.\n");
panic("Cannot remove used "
"space.");
} else {
/*
* The interval of used space can be
448,8 → 452,8
* completely removed.
*/
if (!used_space_remove(area, b, c))
panic("Could not remove used "
"space.\n");
panic("Cannot remove used "
"space.");
}
for (; i < c; i++) {
551,10 → 555,10
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t b = node->key[i];
count_t j;
size_t j;
pte_t *pte;
for (j = 0; j < (count_t) node->value[i]; j++) {
for (j = 0; j < (size_t) node->value[i]; j++) {
page_table_lock(as, false);
pte = page_mapping_find(as, b + j * PAGE_SIZE);
ASSERT(pte && PTE_VALID(pte) &&
769,11 → 773,12
* In order for this to work properly, this may copy the data
* into private anonymous memory (unless it's already there).
*
* @param as Address space.
* @param flags Flags of the area memory.
* @param address Address withing the area to be changed.
* @param as Address space.
* @param flags Flags of the area memory.
* @param address Address within the area to be changed.
*
* @return Zero on success or a value from @ref errno.h on failure.
* @return Zero on success or a value from @ref errno.h on failure.
*
*/
int as_area_change_flags(as_t *as, int flags, uintptr_t address)
{
783,9 → 788,9
ipl_t ipl;
int page_flags;
uintptr_t *old_frame;
index_t frame_idx;
count_t used_pages;
 
size_t frame_idx;
size_t used_pages;
/* Flags for the new memory mapping */
page_flags = area_flags_to_page_flags(flags);
 
799,7 → 804,7
return ENOENT;
}
 
if (area->sh_info || area->backend != &anon_backend) {
if ((area->sh_info) || (area->backend != &anon_backend)) {
/* Copying shared areas not supported yet */
/* Copying non-anonymous memory not supported yet */
mutex_unlock(&area->lock);
822,7 → 827,7
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
used_pages += (count_t) node->value[i];
used_pages += (size_t) node->value[i];
}
}
 
848,10 → 853,10
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t b = node->key[i];
count_t j;
size_t j;
pte_t *pte;
for (j = 0; j < (count_t) node->value[i]; j++) {
for (j = 0; j < (size_t) node->value[i]; j++) {
page_table_lock(as, false);
pte = page_mapping_find(as, b + j * PAGE_SIZE);
ASSERT(pte && PTE_VALID(pte) &&
870,6 → 875,7
*/
 
tlb_invalidate_pages(as->asid, area->base, area->pages);
/*
* Invalidate potential software translation caches (e.g. TSB on
* sparc64).
897,9 → 903,9
node = list_get_instance(cur, btree_node_t, leaf_link);
for (i = 0; i < node->keys; i++) {
uintptr_t b = node->key[i];
count_t j;
size_t j;
for (j = 0; j < (count_t) node->value[i]; j++) {
for (j = 0; j < (size_t) node->value[i]; j++) {
page_table_lock(as, false);
 
/* Insert the new mapping */
1391,16 → 1397,16
*
* @return Zero on failure and non-zero on success.
*/
int used_space_insert(as_area_t *a, uintptr_t page, count_t count)
int used_space_insert(as_area_t *a, uintptr_t page, size_t count)
{
btree_node_t *leaf, *node;
count_t pages;
size_t pages;
unsigned int i;
 
ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
ASSERT(count);
 
pages = (count_t) btree_search(&a->used_space, page, &leaf);
pages = (size_t) btree_search(&a->used_space, page, &leaf);
if (pages) {
/*
* We hit the beginning of some used space.
1417,8 → 1423,8
if (node) {
uintptr_t left_pg = node->key[node->keys - 1];
uintptr_t right_pg = leaf->key[0];
count_t left_cnt = (count_t) node->value[node->keys - 1];
count_t right_cnt = (count_t) leaf->value[0];
size_t left_cnt = (size_t) node->value[node->keys - 1];
size_t right_cnt = (size_t) leaf->value[0];
/*
* Examine the possibility that the interval fits
1472,7 → 1478,7
}
} else if (page < leaf->key[0]) {
uintptr_t right_pg = leaf->key[0];
count_t right_cnt = (count_t) leaf->value[0];
size_t right_cnt = (size_t) leaf->value[0];
/*
* Investigate the border case in which the left neighbour does
1507,8 → 1513,8
if (node) {
uintptr_t left_pg = leaf->key[leaf->keys - 1];
uintptr_t right_pg = node->key[0];
count_t left_cnt = (count_t) leaf->value[leaf->keys - 1];
count_t right_cnt = (count_t) node->value[0];
size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
size_t right_cnt = (size_t) node->value[0];
/*
* Examine the possibility that the interval fits
1562,7 → 1568,7
}
} else if (page >= leaf->key[leaf->keys - 1]) {
uintptr_t left_pg = leaf->key[leaf->keys - 1];
count_t left_cnt = (count_t) leaf->value[leaf->keys - 1];
size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
/*
* Investigate the border case in which the right neighbour
1600,8 → 1606,8
if (page < leaf->key[i]) {
uintptr_t left_pg = leaf->key[i - 1];
uintptr_t right_pg = leaf->key[i];
count_t left_cnt = (count_t) leaf->value[i - 1];
count_t right_cnt = (count_t) leaf->value[i];
size_t left_cnt = (size_t) leaf->value[i - 1];
size_t right_cnt = (size_t) leaf->value[i];
 
/*
* The interval fits between left_pg and right_pg.
1659,8 → 1665,8
}
}
 
panic("Inconsistency detected while adding %" PRIc " pages of used "
"space at %p.\n", count, page);
panic("Inconsistency detected while adding %" PRIs " pages of used "
"space at %p.", count, page);
}
 
/** Mark portion of address space area as unused.
1673,16 → 1679,16
*
* @return Zero on failure and non-zero on success.
*/
int used_space_remove(as_area_t *a, uintptr_t page, count_t count)
int used_space_remove(as_area_t *a, uintptr_t page, size_t count)
{
btree_node_t *leaf, *node;
count_t pages;
size_t pages;
unsigned int i;
 
ASSERT(page == ALIGN_DOWN(page, PAGE_SIZE));
ASSERT(count);
 
pages = (count_t) btree_search(&a->used_space, page, &leaf);
pages = (size_t) btree_search(&a->used_space, page, &leaf);
if (pages) {
/*
* We are lucky, page is the beginning of some interval.
1711,7 → 1717,7
node = btree_leaf_node_left_neighbour(&a->used_space, leaf);
if (node && page < leaf->key[0]) {
uintptr_t left_pg = node->key[node->keys - 1];
count_t left_cnt = (count_t) node->value[node->keys - 1];
size_t left_cnt = (size_t) node->value[node->keys - 1];
 
if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
count * PAGE_SIZE)) {
1727,7 → 1733,7
return 1;
} else if (page + count * PAGE_SIZE <
left_pg + left_cnt*PAGE_SIZE) {
count_t new_cnt;
size_t new_cnt;
/*
* The interval is contained in the rightmost
1751,7 → 1757,7
if (page > leaf->key[leaf->keys - 1]) {
uintptr_t left_pg = leaf->key[leaf->keys - 1];
count_t left_cnt = (count_t) leaf->value[leaf->keys - 1];
size_t left_cnt = (size_t) leaf->value[leaf->keys - 1];
 
if (overlaps(left_pg, left_cnt * PAGE_SIZE, page,
count * PAGE_SIZE)) {
1766,7 → 1772,7
return 1;
} else if (page + count * PAGE_SIZE < left_pg +
left_cnt * PAGE_SIZE) {
count_t new_cnt;
size_t new_cnt;
/*
* The interval is contained in the rightmost
1793,7 → 1799,7
for (i = 1; i < leaf->keys - 1; i++) {
if (page < leaf->key[i]) {
uintptr_t left_pg = leaf->key[i - 1];
count_t left_cnt = (count_t) leaf->value[i - 1];
size_t left_cnt = (size_t) leaf->value[i - 1];
 
/*
* Now the interval is between intervals corresponding
1813,7 → 1819,7
return 1;
} else if (page + count * PAGE_SIZE <
left_pg + left_cnt * PAGE_SIZE) {
count_t new_cnt;
size_t new_cnt;
/*
* The interval is contained in the
1838,8 → 1844,8
}
 
error:
panic("Inconsistency detected while removing %" PRIc " pages of used "
"space from %p.\n", count, page);
panic("Inconsistency detected while removing %" PRIs " pages of used "
"space from %p.", count, page);
}
 
/** Remove reference to address space area share info.
1937,7 → 1943,7
as_area_t *area = node->value[i];
mutex_lock(&area->lock);
printf("as_area: %p, base=%p, pages=%" PRIc
printf("as_area: %p, base=%p, pages=%" PRIs
" (%p - %p)\n", area, area->base, area->pages,
area->base, area->base + FRAMES2SIZE(area->pages));
mutex_unlock(&area->lock);
/branches/arm/kernel/generic/src/mm/frame.c
1,6 → 1,7
/*
* Copyright (c) 2001-2005 Jakub Jermar
* Copyright (c) 2005 Sergey Bondari
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
33,7 → 34,7
 
/**
* @file
* @brief Physical frame allocator.
* @brief Physical frame allocator.
*
* This file contains the physical frame allocator and memory zone management.
* The frame allocator is built on top of the buddy allocator.
41,16 → 42,6
* @see buddy.c
*/
 
/*
* Locking order
*
* In order to access particular zone, the process must first lock
* the zones.lock, then lock the zone and then unlock the zones.lock.
* This insures, that we can fiddle with the zones in runtime without
* affecting the processes.
*
*/
 
#include <arch/types.h>
#include <mm/frame.h>
#include <mm/as.h>
57,7 → 48,6
#include <panic.h>
#include <debug.h>
#include <adt/list.h>
#include <synch/spinlock.h>
#include <synch/mutex.h>
#include <synch/condvar.h>
#include <arch/asm.h>
69,72 → 59,37
#include <macros.h>
#include <config.h>
 
typedef struct {
count_t refcount; /**< tracking of shared frames */
uint8_t buddy_order; /**< buddy system block order */
link_t buddy_link; /**< link to the next free block inside one
order */
void *parent; /**< If allocated by slab, this points there */
} frame_t;
zones_t zones;
 
typedef struct {
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */
pfn_t base; /**< frame_no of the first frame in the frames
array */
count_t count; /**< Size of zone */
 
frame_t *frames; /**< array of frame_t structures in this
zone */
count_t free_count; /**< number of free frame_t structures */
count_t busy_count; /**< number of busy frame_t structures */
buddy_system_t *buddy_system; /**< buddy system for the zone */
int flags;
} zone_t;
 
/*
* The zoneinfo.lock must be locked when accessing zoneinfo structure.
* Some of the attributes in zone_t structures are 'read-only'
*/
 
typedef struct {
SPINLOCK_DECLARE(lock);
unsigned int count;
zone_t *info[ZONES_MAX];
} zones_t;
 
static zones_t zones;
 
/*
* Synchronization primitives used to sleep when there is no memory
* available.
*/
mutex_t mem_avail_mtx;
condvar_t mem_avail_cv;
unsigned long mem_avail_frames = 0; /**< Number of available frames. */
unsigned long mem_avail_gen = 0; /**< Generation counter. */
size_t mem_avail_req = 0; /**< Number of frames requested. */
size_t mem_avail_gen = 0; /**< Generation counter. */
 
/********************/
/* Helper functions */
/********************/
 
static inline index_t frame_index(zone_t *zone, frame_t *frame)
static inline size_t frame_index(zone_t *zone, frame_t *frame)
{
return (index_t) (frame - zone->frames);
return (size_t) (frame - zone->frames);
}
 
static inline index_t frame_index_abs(zone_t *zone, frame_t *frame)
static inline size_t frame_index_abs(zone_t *zone, frame_t *frame)
{
return (index_t) (frame - zone->frames) + zone->base;
return (size_t) (frame - zone->frames) + zone->base;
}
 
static inline int frame_index_valid(zone_t *zone, index_t index)
static inline bool frame_index_valid(zone_t *zone, size_t index)
{
return (index < zone->count);
}
 
/** Compute pfn_t from frame_t pointer & zone pointer */
static index_t make_frame_index(zone_t *zone, frame_t *frame)
static inline size_t make_frame_index(zone_t *zone, frame_t *frame)
{
return (frame - zone->frames);
}
141,7 → 96,8
 
/** Initialize frame structure.
*
* @param frame Frame structure to be initialized.
* @param frame Frame structure to be initialized.
*
*/
static void frame_initialize(frame_t *frame)
{
149,153 → 105,145
frame->buddy_order = 0;
}
 
/**********************/
/* Zoneinfo functions */
/**********************/
/*******************/
/* Zones functions */
/*******************/
 
/** Insert-sort zone into zones list.
*
* @param newzone New zone to be inserted into zone list.
* @return Zone number on success, -1 on error.
* Assume interrupts are disabled and zones lock is
* locked.
*
* @param base Base frame of the newly inserted zone.
* @param count Number of frames of the newly inserted zone.
*
* @return Zone number on success, -1 on error.
*
*/
static int zones_add_zone(zone_t *newzone)
static size_t zones_insert_zone(pfn_t base, size_t count)
{
unsigned int i, j;
ipl_t ipl;
zone_t *z;
 
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
/* Try to merge */
if (zones.count + 1 == ZONES_MAX) {
printf("Maximum zone count %u exceeded!\n", ZONES_MAX);
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return -1;
return (size_t) -1;
}
size_t i;
for (i = 0; i < zones.count; i++) {
/* Check for overflow */
z = zones.info[i];
if (overlaps(newzone->base, newzone->count, z->base,
z->count)) {
/* Check for overlap */
if (overlaps(base, count,
zones.info[i].base, zones.info[i].count)) {
printf("Zones overlap!\n");
return -1;
return (size_t) -1;
}
if (newzone->base < z->base)
if (base < zones.info[i].base)
break;
}
/* Move other zones up */
for (j = i; j < zones.count; j++)
zones.info[j + 1] = zones.info[j];
size_t j;
for (j = zones.count; j > i; j--) {
zones.info[j] = zones.info[j - 1];
zones.info[j].buddy_system->data =
(void *) &zones.info[j - 1];
}
zones.info[i] = newzone;
zones.count++;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
 
return i;
}
 
/** Try to find a zone where can we find the frame.
/** Get total available frames.
*
* Assume interrupts are disabled.
* Assume interrupts are disabled and zones lock is
* locked.
*
* @param frame Frame number contained in zone.
* @param pzone If not null, it is used as zone hint. Zone index is
* filled into the variable on success.
* @return Pointer to locked zone containing frame.
* @return Total number of available frames.
*
*/
static zone_t *find_zone_and_lock(pfn_t frame, unsigned int *pzone)
#ifdef CONFIG_DEBUG
static size_t total_frames_free(void)
{
unsigned int i;
unsigned int hint = pzone ? *pzone : 0;
zone_t *z;
size_t total = 0;
size_t i;
for (i = 0; i < zones.count; i++)
total += zones.info[i].free_count;
spinlock_lock(&zones.lock);
return total;
}
#endif
 
/** Find a zone with a given frames.
*
* Assume interrupts are disabled and zones lock is
* locked.
*
* @param frame Frame number contained in zone.
* @param count Number of frames to look for.
* @param hint Used as zone hint.
*
* @return Zone index or -1 if not found.
*
*/
size_t find_zone(pfn_t frame, size_t count, size_t hint)
{
if (hint >= zones.count)
hint = 0;
i = hint;
size_t i = hint;
do {
z = zones.info[i];
spinlock_lock(&z->lock);
if (z->base <= frame && z->base + z->count > frame) {
/* Unlock the global lock */
spinlock_unlock(&zones.lock);
if (pzone)
*pzone = i;
return z;
}
spinlock_unlock(&z->lock);
 
if ((zones.info[i].base <= frame)
&& (zones.info[i].base + zones.info[i].count >= frame + count))
return i;
i++;
if (i >= zones.count)
i = 0;
} while (i != hint);
 
spinlock_unlock(&zones.lock);
return NULL;
return (size_t) -1;
}
 
/** @return True if zone can allocate specified order */
static int zone_can_alloc(zone_t *z, uint8_t order)
static bool zone_can_alloc(zone_t *zone, uint8_t order)
{
return buddy_system_can_alloc(z->buddy_system, order);
return (zone_flags_available(zone->flags)
&& buddy_system_can_alloc(zone->buddy_system, order));
}
 
/** Find and lock zone that can allocate order frames.
/** Find a zone that can allocate order frames.
*
* Assume interrupts are disabled.
* Assume interrupts are disabled and zones lock is
* locked.
*
* @param order Size (2^order) of free space we are trying to find.
* @param flags Required flags of the target zone.
* @param pzone Pointer to preferred zone or NULL, on return contains
* zone number.
* @param order Size (2^order) of free space we are trying to find.
* @param flags Required flags of the target zone.
* @param hind Preferred zone.
*
*/
static zone_t *
find_free_zone_and_lock(uint8_t order, int flags, unsigned int *pzone)
static size_t find_free_zone(uint8_t order, zone_flags_t flags, size_t hint)
{
unsigned int i;
zone_t *z;
unsigned int hint = pzone ? *pzone : 0;
/* Mask off flags that are not applicable. */
flags &= FRAME_LOW_4_GiB;
 
spinlock_lock(&zones.lock);
if (hint >= zones.count)
hint = 0;
i = hint;
size_t i = hint;
do {
z = zones.info[i];
spinlock_lock(&z->lock);
 
/*
* Check whether the zone meets the search criteria.
*/
if ((z->flags & flags) == flags) {
if ((zones.info[i].flags & flags) == flags) {
/*
* Check if the zone has 2^order frames area available.
*/
if (zone_can_alloc(z, order)) {
spinlock_unlock(&zones.lock);
if (pzone)
*pzone = i;
return z;
}
if (zone_can_alloc(&zones.info[i], order))
return i;
}
spinlock_unlock(&z->lock);
if (++i >= zones.count)
i++;
if (i >= zones.count)
i = 0;
} while (i != hint);
spinlock_unlock(&zones.lock);
return NULL;
return (size_t) -1;
}
 
/**************************/
307,82 → 255,73
* Find block that is parent of current list.
* That means go to lower addresses, until such block is found
*
* @param order Order of parent must be different then this
* parameter!!
* @param order Order of parent must be different then this
* parameter!!
*
*/
static link_t *zone_buddy_find_block(buddy_system_t *b, link_t *child,
static link_t *zone_buddy_find_block(buddy_system_t *buddy, link_t *child,
uint8_t order)
{
frame_t *frame;
zone_t *zone;
index_t index;
frame_t *frame = list_get_instance(child, frame_t, buddy_link);
zone_t *zone = (zone_t *) buddy->data;
frame = list_get_instance(child, frame_t, buddy_link);
zone = (zone_t *) b->data;
 
index = frame_index(zone, frame);
size_t index = frame_index(zone, frame);
do {
if (zone->frames[index].buddy_order != order) {
if (zone->frames[index].buddy_order != order)
return &zone->frames[index].buddy_link;
}
} while(index-- > 0);
} while (index-- > 0);
return NULL;
}
 
/** Buddy system find_buddy implementation.
*
* @param b Buddy system.
* @param block Block for which buddy should be found.
* @param buddy Buddy system.
* @param block Block for which buddy should be found.
*
* @return Buddy for given block if found.
* @return Buddy for given block if found.
*
*/
static link_t *zone_buddy_find_buddy(buddy_system_t *b, link_t *block)
static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, link_t *block)
{
frame_t *frame;
zone_t *zone;
index_t index;
bool is_left, is_right;
 
frame = list_get_instance(block, frame_t, buddy_link);
zone = (zone_t *) b->data;
frame_t *frame = list_get_instance(block, frame_t, buddy_link);
zone_t *zone = (zone_t *) buddy->data;
ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame),
frame->buddy_order));
is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame);
 
ASSERT(is_left ^ is_right);
bool is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame);
size_t index;
if (is_left) {
index = (frame_index(zone, frame)) +
(1 << frame->buddy_order);
} else { /* if (is_right) */
} else { /* is_right */
index = (frame_index(zone, frame)) -
(1 << frame->buddy_order);
}
if (frame_index_valid(zone, index)) {
if (zone->frames[index].buddy_order == frame->buddy_order &&
zone->frames[index].refcount == 0) {
if ((zone->frames[index].buddy_order == frame->buddy_order) &&
(zone->frames[index].refcount == 0)) {
return &zone->frames[index].buddy_link;
}
}
 
return NULL;
return NULL;
}
 
/** Buddy system bisect implementation.
*
* @param b Buddy system.
* @param block Block to bisect.
* @param buddy Buddy system.
* @param block Block to bisect.
*
* @return Right block.
* @return Right block.
*
*/
static link_t *zone_buddy_bisect(buddy_system_t *b, link_t *block)
static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block)
{
frame_t *frame_l, *frame_r;
 
frame_l = list_get_instance(block, frame_t, buddy_link);
frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
frame_t *frame_l = list_get_instance(block, frame_t, buddy_link);
frame_t *frame_r = (frame_l + (1 << (frame_l->buddy_order - 1)));
return &frame_r->buddy_link;
}
389,75 → 328,68
 
/** Buddy system coalesce implementation.
*
* @param b Buddy system.
* @param block_1 First block.
* @param block_2 First block's buddy.
* @param buddy Buddy system.
* @param block_1 First block.
* @param block_2 First block's buddy.
*
* @return Coalesced block (actually block that represents lower
* address).
* @return Coalesced block (actually block that represents lower
* address).
*
*/
static link_t *zone_buddy_coalesce(buddy_system_t *b, link_t *block_1,
link_t *block_2)
static link_t *zone_buddy_coalesce(buddy_system_t *buddy, link_t *block_1,
link_t *block_2)
{
frame_t *frame1, *frame2;
frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link);
frame_t *frame2 = list_get_instance(block_2, frame_t, buddy_link);
frame1 = list_get_instance(block_1, frame_t, buddy_link);
frame2 = list_get_instance(block_2, frame_t, buddy_link);
return frame1 < frame2 ? block_1 : block_2;
return ((frame1 < frame2) ? block_1 : block_2);
}
 
/** Buddy system set_order implementation.
*
* @param b Buddy system.
* @param block Buddy system block.
* @param order Order to set.
* @param buddy Buddy system.
* @param block Buddy system block.
* @param order Order to set.
*
*/
static void zone_buddy_set_order(buddy_system_t *b, link_t *block,
static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block,
uint8_t order)
{
frame_t *frame;
frame = list_get_instance(block, frame_t, buddy_link);
frame->buddy_order = order;
list_get_instance(block, frame_t, buddy_link)->buddy_order = order;
}
 
/** Buddy system get_order implementation.
*
* @param b Buddy system.
* @param block Buddy system block.
* @param buddy Buddy system.
* @param block Buddy system block.
*
* @return Order of block.
* @return Order of block.
*
*/
static uint8_t zone_buddy_get_order(buddy_system_t *b, link_t *block)
static uint8_t zone_buddy_get_order(buddy_system_t *buddy, link_t *block)
{
frame_t *frame;
frame = list_get_instance(block, frame_t, buddy_link);
return frame->buddy_order;
return list_get_instance(block, frame_t, buddy_link)->buddy_order;
}
 
/** Buddy system mark_busy implementation.
*
* @param b Buddy system.
* @param block Buddy system block.
* @param buddy Buddy system.
* @param block Buddy system block.
*
*/
static void zone_buddy_mark_busy(buddy_system_t *b, link_t * block)
static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t * block)
{
frame_t * frame;
 
frame = list_get_instance(block, frame_t, buddy_link);
frame->refcount = 1;
list_get_instance(block, frame_t, buddy_link)->refcount = 1;
}
 
/** Buddy system mark_available implementation.
*
* @param b Buddy system.
* @param block Buddy system block.
* @param buddy Buddy system.
* @param block Buddy system block.
*/
static void zone_buddy_mark_available(buddy_system_t *b, link_t *block)
static void zone_buddy_mark_available(buddy_system_t *buddy, link_t *block)
{
frame_t *frame;
frame = list_get_instance(block, frame_t, buddy_link);
frame->refcount = 0;
list_get_instance(block, frame_t, buddy_link)->refcount = 0;
}
 
static buddy_system_operations_t zone_buddy_system_operations = {
477,60 → 409,57
 
/** Allocate frame in particular zone.
*
* Assume zone is locked.
* Assume zone is locked and is available for allocation.
* Panics if allocation is impossible.
*
* @param zone Zone to allocate from.
* @param order Allocate exactly 2^order frames.
* @param zone Zone to allocate from.
* @param order Allocate exactly 2^order frames.
*
* @return Frame index in zone.
* @return Frame index in zone.
*
*/
static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order)
{
pfn_t v;
link_t *tmp;
frame_t *frame;
 
ASSERT(zone_flags_available(zone->flags));
/* Allocate frames from zone buddy system */
tmp = buddy_system_alloc(zone->buddy_system, order);
link_t *link = buddy_system_alloc(zone->buddy_system, order);
ASSERT(tmp);
ASSERT(link);
/* Update zone information. */
zone->free_count -= (1 << order);
zone->busy_count += (1 << order);
 
/* Frame will be actually a first frame of the block. */
frame = list_get_instance(tmp, frame_t, buddy_link);
frame_t *frame = list_get_instance(link, frame_t, buddy_link);
/* get frame address */
v = make_frame_index(zone, frame);
return v;
/* Get frame address */
return make_frame_index(zone, frame);
}
 
/** Free frame from zone.
*
* Assume zone is locked.
* Assume zone is locked and is available for deallocation.
*
* @param zone Pointer to zone from which the frame is to be freed.
* @param frame_idx Frame index relative to zone.
* @param zone Pointer to zone from which the frame is to be freed.
* @param frame_idx Frame index relative to zone.
*
*/
static void zone_frame_free(zone_t *zone, index_t frame_idx)
static void zone_frame_free(zone_t *zone, size_t frame_idx)
{
frame_t *frame;
uint8_t order;
 
frame = &zone->frames[frame_idx];
ASSERT(zone_flags_available(zone->flags));
/* remember frame order */
order = frame->buddy_order;
 
frame_t *frame = &zone->frames[frame_idx];
/* Remember frame order */
uint8_t order = frame->buddy_order;
ASSERT(frame->refcount);
 
if (!--frame->refcount) {
buddy_system_free(zone->buddy_system, &frame->buddy_link);
/* Update zone information. */
zone->free_count += (1 << order);
zone->busy_count -= (1 << order);
538,7 → 467,7
}
 
/** Return frame from zone. */
static frame_t *zone_get_frame(zone_t *zone, index_t frame_idx)
static frame_t *zone_get_frame(zone_t *zone, size_t frame_idx)
{
ASSERT(frame_idx < zone->count);
return &zone->frames[frame_idx];
545,569 → 474,648
}
 
/** Mark frame in zone unavailable to allocation. */
static void zone_mark_unavailable(zone_t *zone, index_t frame_idx)
static void zone_mark_unavailable(zone_t *zone, size_t frame_idx)
{
frame_t *frame;
link_t *link;
 
frame = zone_get_frame(zone, frame_idx);
ASSERT(zone_flags_available(zone->flags));
frame_t *frame = zone_get_frame(zone, frame_idx);
if (frame->refcount)
return;
link_t *link __attribute__ ((unused));
link = buddy_system_alloc_block(zone->buddy_system,
&frame->buddy_link);
ASSERT(link);
zone->free_count--;
 
mutex_lock(&mem_avail_mtx);
mem_avail_frames--;
mutex_unlock(&mem_avail_mtx);
}
 
/** Join two zones.
/** Merge two zones.
*
* Expect zone_t *z to point to space at least zone_conf_size large.
* Expect buddy to point to space at least zone_conf_size large.
* Assume z1 & z2 are locked and compatible and zones lock is
* locked.
*
* Assume z1 & z2 are locked.
* @param z1 First zone to merge.
* @param z2 Second zone to merge.
* @param old_z1 Original date of the first zone.
* @param buddy Merged zone buddy.
*
* @param z Target zone structure pointer.
* @param z1 Zone to merge.
* @param z2 Zone to merge.
*/
static void _zone_merge(zone_t *z, zone_t *z1, zone_t *z2)
static void zone_merge_internal(size_t z1, size_t z2, zone_t *old_z1, buddy_system_t *buddy)
{
uint8_t max_order;
unsigned int i;
int z2idx;
pfn_t frame_idx;
frame_t *frame;
 
ASSERT(!overlaps(z1->base, z1->count, z2->base, z2->count));
ASSERT(z1->base < z2->base);
 
spinlock_initialize(&z->lock, "zone_lock");
z->base = z1->base;
z->count = z2->base + z2->count - z1->base;
z->flags = z1->flags & z2->flags;
 
z->free_count = z1->free_count + z2->free_count;
z->busy_count = z1->busy_count + z2->busy_count;
ASSERT(zone_flags_available(zones.info[z1].flags));
ASSERT(zone_flags_available(zones.info[z2].flags));
ASSERT(zones.info[z1].flags == zones.info[z2].flags);
ASSERT(zones.info[z1].base < zones.info[z2].base);
ASSERT(!overlaps(zones.info[z1].base, zones.info[z1].count,
zones.info[z2].base, zones.info[z2].count));
max_order = fnzb(z->count);
 
z->buddy_system = (buddy_system_t *) &z[1];
buddy_system_create(z->buddy_system, max_order,
&zone_buddy_system_operations, (void *) z);
 
z->frames = (frame_t *)((uint8_t *) z->buddy_system +
buddy_conf_size(max_order));
for (i = 0; i < z->count; i++) {
/* This marks all frames busy */
frame_initialize(&z->frames[i]);
}
/* Difference between zone bases */
pfn_t base_diff = zones.info[z2].base - zones.info[z1].base;
zones.info[z1].count = base_diff + zones.info[z2].count;
zones.info[z1].free_count += zones.info[z2].free_count;
zones.info[z1].busy_count += zones.info[z2].busy_count;
zones.info[z1].buddy_system = buddy;
uint8_t order = fnzb(zones.info[z1].count);
buddy_system_create(zones.info[z1].buddy_system, order,
&zone_buddy_system_operations, (void *) &zones.info[z1]);
zones.info[z1].frames =
(frame_t *) ((uint8_t *) zones.info[z1].buddy_system
+ buddy_conf_size(order));
/* This marks all frames busy */
size_t i;
for (i = 0; i < zones.info[z1].count; i++)
frame_initialize(&zones.info[z1].frames[i]);
/* Copy frames from both zones to preserve full frame orders,
* parents etc. Set all free frames with refcount=0 to 1, because
* we add all free frames to buddy allocator later again, clear
* order to 0. Don't set busy frames with refcount=0, as they
* parents etc. Set all free frames with refcount = 0 to 1, because
* we add all free frames to buddy allocator later again, clearing
* order to 0. Don't set busy frames with refcount = 0, as they
* will not be reallocated during merge and it would make later
* problems with allocation/free.
*/
for (i = 0; i < z1->count; i++)
z->frames[i] = z1->frames[i];
for (i = 0; i < z2->count; i++) {
z2idx = i + (z2->base - z1->base);
z->frames[z2idx] = z2->frames[i];
}
for (i = 0; i < old_z1->count; i++)
zones.info[z1].frames[i] = old_z1->frames[i];
for (i = 0; i < zones.info[z2].count; i++)
zones.info[z1].frames[base_diff + i]
= zones.info[z2].frames[i];
i = 0;
while (i < z->count) {
if (z->frames[i].refcount) {
/* skip busy frames */
i += 1 << z->frames[i].buddy_order;
} else { /* Free frames, set refcount=1 */
/* All free frames have refcount=0, we need not
* to check the order */
z->frames[i].refcount = 1;
z->frames[i].buddy_order = 0;
while (i < zones.info[z1].count) {
if (zones.info[z1].frames[i].refcount) {
/* Skip busy frames */
i += 1 << zones.info[z1].frames[i].buddy_order;
} else {
/* Free frames, set refcount = 1
* (all free frames have refcount == 0, we need not
* to check the order)
*/
zones.info[z1].frames[i].refcount = 1;
zones.info[z1].frames[i].buddy_order = 0;
i++;
}
}
/* Add free blocks from the 2 original zones */
while (zone_can_alloc(z1, 0)) {
frame_idx = zone_frame_alloc(z1, 0);
frame = &z->frames[frame_idx];
/* Add free blocks from the original zone z1 */
while (zone_can_alloc(old_z1, 0)) {
/* Allocate from the original zone */
pfn_t frame_idx = zone_frame_alloc(old_z1, 0);
/* Free the frame from the merged zone */
frame_t *frame = &zones.info[z1].frames[frame_idx];
frame->refcount = 0;
buddy_system_free(z->buddy_system, &frame->buddy_link);
buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link);
}
while (zone_can_alloc(z2, 0)) {
frame_idx = zone_frame_alloc(z2, 0);
frame = &z->frames[frame_idx + (z2->base - z1->base)];
/* Add free blocks from the original zone z2 */
while (zone_can_alloc(&zones.info[z2], 0)) {
/* Allocate from the original zone */
pfn_t frame_idx = zone_frame_alloc(&zones.info[z2], 0);
/* Free the frame from the merged zone */
frame_t *frame = &zones.info[z1].frames[base_diff + frame_idx];
frame->refcount = 0;
buddy_system_free(z->buddy_system, &frame->buddy_link);
buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link);
}
}
 
/** Return old configuration frames into the zone.
*
* We have several cases
* - the conf. data is outside of zone -> exit, shall we call frame_free??
* - the conf. data was created by zone_create or
* updated with reduce_region -> free every frame
* We have two cases:
* - The configuration data is outside the zone
* -> do nothing (perhaps call frame_free?)
* - The configuration data was created by zone_create
* or updated by reduce_region -> free every frame
*
* @param newzone The actual zone where freeing should occur.
* @param oldzone Pointer to old zone configuration data that should
* be freed from new zone.
* @param znum The actual zone where freeing should occur.
* @param pfn Old zone configuration frame.
* @param count Old zone frame count.
*
*/
static void return_config_frames(zone_t *newzone, zone_t *oldzone)
static void return_config_frames(size_t znum, pfn_t pfn, size_t count)
{
pfn_t pfn;
frame_t *frame;
count_t cframes;
unsigned int i;
 
pfn = ADDR2PFN((uintptr_t)KA2PA(oldzone));
cframes = SIZE2FRAMES(zone_conf_size(oldzone->count));
ASSERT(zone_flags_available(zones.info[znum].flags));
if (pfn < newzone->base || pfn >= newzone->base + newzone->count)
size_t cframes = SIZE2FRAMES(zone_conf_size(count));
if ((pfn < zones.info[znum].base)
|| (pfn >= zones.info[znum].base + zones.info[znum].count))
return;
frame_t *frame __attribute__ ((unused));
 
frame = &newzone->frames[pfn - newzone->base];
frame = &zones.info[znum].frames[pfn - zones.info[znum].base];
ASSERT(!frame->buddy_order);
 
size_t i;
for (i = 0; i < cframes; i++) {
newzone->busy_count++;
zone_frame_free(newzone, pfn+i-newzone->base);
zones.info[znum].busy_count++;
zone_frame_free(&zones.info[znum],
pfn - zones.info[znum].base + i);
}
}
 
/** Reduce allocated block to count of order 0 frames.
*
* The allocated block need 2^order frames of space. Reduce all frames
* in block to order 0 and free the unneeded frames. This means, that
* when freeing the previously allocated block starting with frame_idx,
* The allocated block needs 2^order frames. Reduce all frames
* in the block to order 0 and free the unneeded frames. This means that
* when freeing the previously allocated block starting with frame_idx,
* you have to free every frame.
*
* @param zone
* @param frame_idx Index to block.
* @param count Allocated space in block.
* @param znum Zone.
* @param frame_idx Index the first frame of the block.
* @param count Allocated frames in block.
*
*/
static void zone_reduce_region(zone_t *zone, pfn_t frame_idx, count_t count)
static void zone_reduce_region(size_t znum, pfn_t frame_idx, size_t count)
{
count_t i;
uint8_t order;
frame_t *frame;
ASSERT(zone_flags_available(zones.info[znum].flags));
ASSERT(frame_idx + count < zones.info[znum].count);
ASSERT(frame_idx + count < zone->count);
 
order = zone->frames[frame_idx].buddy_order;
ASSERT((count_t) (1 << order) >= count);
 
uint8_t order = zones.info[znum].frames[frame_idx].buddy_order;
ASSERT((size_t) (1 << order) >= count);
/* Reduce all blocks to order 0 */
for (i = 0; i < (count_t) (1 << order); i++) {
frame = &zone->frames[i + frame_idx];
size_t i;
for (i = 0; i < (size_t) (1 << order); i++) {
frame_t *frame = &zones.info[znum].frames[i + frame_idx];
frame->buddy_order = 0;
if (!frame->refcount)
frame->refcount = 1;
ASSERT(frame->refcount == 1);
}
/* Free unneeded frames */
for (i = count; i < (count_t) (1 << order); i++) {
zone_frame_free(zone, i + frame_idx);
}
for (i = count; i < (size_t) (1 << order); i++)
zone_frame_free(&zones.info[znum], i + frame_idx);
}
 
/** Merge zones z1 and z2.
*
* - the zones must be 2 zones with no zone existing in between,
* which means that z2 = z1+1
* The merged zones must be 2 zones with no zone existing in between
* (which means that z2 = z1 + 1). Both zones must be available zones
* with the same flags.
*
* - When you create a new zone, the frame allocator configuration does
* not to be 2^order size. Once the allocator is running it is no longer
* possible, merged configuration data occupies more space :-/
* When you create a new zone, the frame allocator configuration does
* not to be 2^order size. Once the allocator is running it is no longer
* possible, merged configuration data occupies more space :-/
*
* The function uses
*
*/
void zone_merge(unsigned int z1, unsigned int z2)
bool zone_merge(size_t z1, size_t z2)
{
ipl_t ipl;
zone_t *zone1, *zone2, *newzone;
unsigned int cframes;
uint8_t order;
unsigned int i;
pfn_t pfn;
 
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
 
if ((z1 >= zones.count) || (z2 >= zones.count))
bool ret = true;
/* We can join only 2 zones with none existing inbetween,
* the zones have to be available and with the same
* set of flags
*/
if ((z1 >= zones.count) || (z2 >= zones.count)
|| (z2 - z1 != 1)
|| (!zone_flags_available(zones.info[z1].flags))
|| (!zone_flags_available(zones.info[z2].flags))
|| (zones.info[z1].flags != zones.info[z2].flags)) {
ret = false;
goto errout;
/* We can join only 2 zones with none existing inbetween */
if (z2 - z1 != 1)
goto errout;
 
zone1 = zones.info[z1];
zone2 = zones.info[z2];
spinlock_lock(&zone1->lock);
spinlock_lock(&zone2->lock);
 
cframes = SIZE2FRAMES(zone_conf_size(zone2->base + zone2->count -
zone1->base));
}
pfn_t cframes = SIZE2FRAMES(zone_conf_size(
zones.info[z2].base - zones.info[z1].base
+ zones.info[z2].count));
uint8_t order;
if (cframes == 1)
order = 0;
else
else
order = fnzb(cframes - 1) + 1;
 
/* Allocate zonedata inside one of the zones */
if (zone_can_alloc(zone1, order))
pfn = zone1->base + zone_frame_alloc(zone1, order);
else if (zone_can_alloc(zone2, order))
pfn = zone2->base + zone_frame_alloc(zone2, order);
else
goto errout2;
 
newzone = (zone_t *) PA2KA(PFN2ADDR(pfn));
 
_zone_merge(newzone, zone1, zone2);
 
/* Allocate merged zone data inside one of the zones */
pfn_t pfn;
if (zone_can_alloc(&zones.info[z1], order)) {
pfn = zones.info[z1].base + zone_frame_alloc(&zones.info[z1], order);
} else if (zone_can_alloc(&zones.info[z2], order)) {
pfn = zones.info[z2].base + zone_frame_alloc(&zones.info[z2], order);
} else {
ret = false;
goto errout;
}
/* Preserve original data from z1 */
zone_t old_z1 = zones.info[z1];
old_z1.buddy_system->data = (void *) &old_z1;
/* Do zone merging */
buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(pfn));
zone_merge_internal(z1, z2, &old_z1, buddy);
/* Free unneeded config frames */
zone_reduce_region(newzone, pfn - newzone->base, cframes);
zone_reduce_region(z1, pfn - zones.info[z1].base, cframes);
/* Subtract zone information from busy frames */
newzone->busy_count -= cframes;
 
/* Replace existing zones in zoneinfo list */
zones.info[z1] = newzone;
for (i = z2 + 1; i < zones.count; i++)
zones.info[z1].busy_count -= cframes;
/* Free old zone information */
return_config_frames(z1,
ADDR2PFN(KA2PA((uintptr_t) old_z1.frames)), old_z1.count);
return_config_frames(z1,
ADDR2PFN(KA2PA((uintptr_t) zones.info[z2].frames)),
zones.info[z2].count);
/* Move zones down */
size_t i;
for (i = z2 + 1; i < zones.count; i++) {
zones.info[i - 1] = zones.info[i];
zones.info[i - 1].buddy_system->data =
(void *) &zones.info[i - 1];
}
zones.count--;
 
/* Free old zone information */
return_config_frames(newzone, zone1);
return_config_frames(newzone, zone2);
errout2:
/* Nobody is allowed to enter to zone, so we are safe
* to touch the spinlocks last time */
spinlock_unlock(&zone1->lock);
spinlock_unlock(&zone2->lock);
errout:
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return ret;
}
 
/** Merge all zones into one big zone.
/** Merge all mergeable zones into one big zone.
*
* It is reasonable to do this on systems whose bios reports parts in chunks,
* so that we could have 1 zone (it's faster).
* It is reasonable to do this on systems where
* BIOS reports parts in chunks, so that we could
* have 1 zone (it's faster).
*
*/
void zone_merge_all(void)
{
int count = zones.count;
 
while (zones.count > 1 && --count) {
zone_merge(0, 1);
break;
size_t i = 0;
while (i < zones.count) {
if (!zone_merge(i, i + 1))
i++;
}
}
 
/** Create new frame zone.
*
* @param start Physical address of the first frame within the zone.
* @param count Count of frames in zone.
* @param z Address of configuration information of zone.
* @param flags Zone flags.
* @param zone Zone to construct.
* @param buddy Address of buddy system configuration information.
* @param start Physical address of the first frame within the zone.
* @param count Count of frames in zone.
* @param flags Zone flags.
*
* @return Initialized zone.
* @return Initialized zone.
*
*/
static void zone_construct(pfn_t start, count_t count, zone_t *z, int flags)
static void zone_construct(zone_t *zone, buddy_system_t *buddy, pfn_t start, size_t count, zone_flags_t flags)
{
unsigned int i;
uint8_t max_order;
 
spinlock_initialize(&z->lock, "zone_lock");
z->base = start;
z->count = count;
 
/* Mask off flags that are calculated automatically. */
flags &= ~FRAME_LOW_4_GiB;
/* Determine calculated flags. */
if (z->base + count < (1ULL << (32 - FRAME_WIDTH))) /* 4 GiB */
flags |= FRAME_LOW_4_GiB;
 
z->flags = flags;
 
z->free_count = count;
z->busy_count = 0;
 
/*
* Compute order for buddy system, initialize
*/
max_order = fnzb(count);
z->buddy_system = (buddy_system_t *)&z[1];
zone->base = start;
zone->count = count;
zone->flags = flags;
zone->free_count = count;
zone->busy_count = 0;
zone->buddy_system = buddy;
buddy_system_create(z->buddy_system, max_order,
&zone_buddy_system_operations, (void *) z);
/* Allocate frames _after_ the conframe */
/* Check sizes */
z->frames = (frame_t *)((uint8_t *) z->buddy_system +
buddy_conf_size(max_order));
for (i = 0; i < count; i++) {
frame_initialize(&z->frames[i]);
}
/* Stuffing frames */
for (i = 0; i < count; i++) {
z->frames[i].refcount = 0;
buddy_system_free(z->buddy_system, &z->frames[i].buddy_link);
}
if (zone_flags_available(flags)) {
/*
* Compute order for buddy system and initialize
*/
uint8_t order = fnzb(count);
buddy_system_create(zone->buddy_system, order,
&zone_buddy_system_operations, (void *) zone);
/* Allocate frames _after_ the confframe */
/* Check sizes */
zone->frames = (frame_t *) ((uint8_t *) zone->buddy_system +
buddy_conf_size(order));
size_t i;
for (i = 0; i < count; i++)
frame_initialize(&zone->frames[i]);
/* Stuffing frames */
for (i = 0; i < count; i++) {
zone->frames[i].refcount = 0;
buddy_system_free(zone->buddy_system, &zone->frames[i].buddy_link);
}
} else
zone->frames = NULL;
}
 
/** Compute configuration data size for zone.
*
* @param count Size of zone in frames.
* @return Size of zone configuration info (in bytes).
* @param count Size of zone in frames.
*
* @return Size of zone configuration info (in bytes).
*
*/
uintptr_t zone_conf_size(count_t count)
uintptr_t zone_conf_size(size_t count)
{
int size = sizeof(zone_t) + count * sizeof(frame_t);
int max_order;
 
max_order = fnzb(count);
size += buddy_conf_size(max_order);
return size;
return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count)));
}
 
/** Create and add zone to system.
*
* @param start First frame number (absolute).
* @param count Size of zone in frames.
* @param confframe Where configuration frames are supposed to be.
* Automatically checks, that we will not disturb the
* kernel and possibly init. If confframe is given
* _outside_ this zone, it is expected, that the area is
* already marked BUSY and big enough to contain
* zone_conf_size() amount of data. If the confframe is
* inside the area, the zone free frame information is
* modified not to include it.
* @param start First frame number (absolute).
* @param count Size of zone in frames.
* @param confframe Where configuration frames are supposed to be.
* Automatically checks, that we will not disturb the
* kernel and possibly init. If confframe is given
* _outside_ this zone, it is expected, that the area is
* already marked BUSY and big enough to contain
* zone_conf_size() amount of data. If the confframe is
* inside the area, the zone free frame information is
* modified not to include it.
*
* @return Zone number or -1 on error.
* @return Zone number or -1 on error.
*
*/
int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags)
size_t zone_create(pfn_t start, size_t count, pfn_t confframe, zone_flags_t flags)
{
zone_t *z;
uintptr_t addr;
count_t confcount;
unsigned int i;
int znum;
 
/* Theoretically we could have here 0, practically make sure
* nobody tries to do that. If some platform requires, remove
* the assert
*/
ASSERT(confframe);
/* If conframe is supposed to be inside our zone, then make sure
* it does not span kernel & init
*/
confcount = SIZE2FRAMES(zone_conf_size(count));
if (confframe >= start && confframe < start + count) {
for (; confframe < start + count; confframe++) {
addr = PFN2ADDR(confframe);
if (overlaps(addr, PFN2ADDR(confcount),
KA2PA(config.base), config.kernel_size))
continue;
if (overlaps(addr, PFN2ADDR(confcount),
KA2PA(config.stack_base), config.stack_size))
continue;
bool overlap = false;
count_t i;
for (i = 0; i < init.cnt; i++)
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
if (zone_flags_available(flags)) { /* Create available zone */
/* Theoretically we could have NULL here, practically make sure
* nobody tries to do that. If some platform requires, remove
* the assert
*/
ASSERT(confframe != NULL);
/* If confframe is supposed to be inside our zone, then make sure
* it does not span kernel & init
*/
size_t confcount = SIZE2FRAMES(zone_conf_size(count));
if ((confframe >= start) && (confframe < start + count)) {
for (; confframe < start + count; confframe++) {
uintptr_t addr = PFN2ADDR(confframe);
if (overlaps(addr, PFN2ADDR(confcount),
KA2PA(init.tasks[i].addr),
init.tasks[i].size)) {
overlap = true;
break;
}
if (overlap)
continue;
KA2PA(config.base), config.kernel_size))
continue;
if (overlaps(addr, PFN2ADDR(confcount),
KA2PA(config.stack_base), config.stack_size))
continue;
bool overlap = false;
size_t i;
for (i = 0; i < init.cnt; i++)
if (overlaps(addr, PFN2ADDR(confcount),
KA2PA(init.tasks[i].addr),
init.tasks[i].size)) {
overlap = true;
break;
}
if (overlap)
continue;
break;
}
break;
if (confframe >= start + count)
panic("Cannot find configuration data for zone.");
}
if (confframe >= start + count)
panic("Cannot find configuration data for zone.");
size_t znum = zones_insert_zone(start, count);
if (znum == (size_t) -1) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return (size_t) -1;
}
buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(confframe));
zone_construct(&zones.info[znum], buddy, start, count, flags);
/* If confdata in zone, mark as unavailable */
if ((confframe >= start) && (confframe < start + count)) {
size_t i;
for (i = confframe; i < confframe + confcount; i++)
zone_mark_unavailable(&zones.info[znum],
i - zones.info[znum].base);
}
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return znum;
}
 
z = (zone_t *) PA2KA(PFN2ADDR(confframe));
zone_construct(start, count, z, flags);
znum = zones_add_zone(z);
if (znum == -1)
return -1;
 
mutex_lock(&mem_avail_mtx);
mem_avail_frames += count;
mutex_unlock(&mem_avail_mtx);
 
/* If confdata in zone, mark as unavailable */
if (confframe >= start && confframe < start + count)
for (i = confframe; i < confframe + confcount; i++) {
zone_mark_unavailable(z, i - z->base);
}
/* Non-available zone */
size_t znum = zones_insert_zone(start, count);
if (znum == (size_t) -1) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return (size_t) -1;
}
zone_construct(&zones.info[znum], NULL, start, count, flags);
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return znum;
}
 
/***************************************/
/*******************/
/* Frame functions */
/*******************/
 
/** Set parent of frame. */
void frame_set_parent(pfn_t pfn, void *data, unsigned int hint)
void frame_set_parent(pfn_t pfn, void *data, size_t hint)
{
zone_t *zone = find_zone_and_lock(pfn, &hint);
 
ASSERT(zone);
 
zone_get_frame(zone, pfn - zone->base)->parent = data;
spinlock_unlock(&zone->lock);
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
size_t znum = find_zone(pfn, 1, hint);
ASSERT(znum != (size_t) -1);
zone_get_frame(&zones.info[znum],
pfn - zones.info[znum].base)->parent = data;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
}
 
void *frame_get_parent(pfn_t pfn, unsigned int hint)
void *frame_get_parent(pfn_t pfn, size_t hint)
{
zone_t *zone = find_zone_and_lock(pfn, &hint);
void *res;
 
ASSERT(zone);
res = zone_get_frame(zone, pfn - zone->base)->parent;
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
spinlock_unlock(&zone->lock);
size_t znum = find_zone(pfn, 1, hint);
ASSERT(znum != (size_t) -1);
void *res = zone_get_frame(&zones.info[znum],
pfn - zones.info[znum].base)->parent;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return res;
}
 
/** Allocate power-of-two frames of physical memory.
*
* @param order Allocate exactly 2^order frames.
* @param flags Flags for host zone selection and address processing.
* @param pzone Preferred zone.
* @param order Allocate exactly 2^order frames.
* @param flags Flags for host zone selection and address processing.
* @param pzone Preferred zone.
*
* @return Physical address of the allocated frame.
* @return Physical address of the allocated frame.
*
*/
void *frame_alloc_generic(uint8_t order, int flags, unsigned int *pzone)
void *frame_alloc_generic(uint8_t order, frame_flags_t flags, size_t *pzone)
{
size_t size = ((size_t) 1) << order;
ipl_t ipl;
int freed;
pfn_t v;
zone_t *zone;
unsigned long gen = 0;
size_t hint = pzone ? (*pzone) : 0;
loop:
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
/*
* First, find suitable frame zone.
*/
zone = find_free_zone_and_lock(order, flags, pzone);
size_t znum = find_free_zone(order,
FRAME_TO_ZONE_FLAGS(flags), hint);
/* If no memory, reclaim some slab memory,
if it does not help, reclaim all */
if (!zone && !(flags & FRAME_NO_RECLAIM)) {
freed = slab_reclaim(0);
if (freed)
zone = find_free_zone_and_lock(order, flags, pzone);
if (!zone) {
if ((znum == (size_t) -1) && (!(flags & FRAME_NO_RECLAIM))) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
size_t freed = slab_reclaim(0);
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
if (freed > 0)
znum = find_free_zone(order,
FRAME_TO_ZONE_FLAGS(flags), hint);
if (znum == (size_t) -1) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
freed = slab_reclaim(SLAB_RECLAIM_ALL);
if (freed)
zone = find_free_zone_and_lock(order, flags,
pzone);
ipl = interrupts_disable();
spinlock_lock(&zones.lock);
if (freed > 0)
znum = find_free_zone(order,
FRAME_TO_ZONE_FLAGS(flags), hint);
}
}
if (!zone) {
/*
* Sleep until some frames are available again.
*/
if (znum == (size_t) -1) {
if (flags & FRAME_ATOMIC) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
return 0;
return NULL;
}
#ifdef CONFIG_DEBUG
unsigned long avail;
 
mutex_lock(&mem_avail_mtx);
avail = mem_avail_frames;
mutex_unlock(&mem_avail_mtx);
 
printf("Thread %" PRIu64 " waiting for %u frames, "
"%u available.\n", THREAD->tid, 1ULL << order, avail);
size_t avail = total_frames_free();
#endif
 
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
/*
* Sleep until some frames are available again.
*/
#ifdef CONFIG_DEBUG
printf("Thread %" PRIu64 " waiting for %" PRIs " frames, "
"%" PRIs " available.\n", THREAD->tid, size, avail);
#endif
mutex_lock(&mem_avail_mtx);
while ((mem_avail_frames < (1ULL << order)) ||
gen == mem_avail_gen)
if (mem_avail_req > 0)
mem_avail_req = min(mem_avail_req, size);
else
mem_avail_req = size;
size_t gen = mem_avail_gen;
while (gen == mem_avail_gen)
condvar_wait(&mem_avail_cv, &mem_avail_mtx);
gen = mem_avail_gen;
mutex_unlock(&mem_avail_mtx);
 
#ifdef CONFIG_DEBUG
mutex_lock(&mem_avail_mtx);
avail = mem_avail_frames;
mutex_unlock(&mem_avail_mtx);
 
printf("Thread %" PRIu64 " woken up, %u frames available.\n",
THREAD->tid, avail);
printf("Thread %" PRIu64 " woken up.\n", THREAD->tid);
#endif
 
interrupts_restore(ipl);
goto loop;
}
v = zone_frame_alloc(zone, order);
v += zone->base;
 
spinlock_unlock(&zone->lock);
pfn_t pfn = zone_frame_alloc(&zones.info[znum], order)
+ zones.info[znum].base;
mutex_lock(&mem_avail_mtx);
mem_avail_frames -= (1ULL << order);
mutex_unlock(&mem_avail_mtx);
 
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
 
if (pzone)
*pzone = znum;
if (flags & FRAME_KA)
return (void *)PA2KA(PFN2ADDR(v));
return (void *)PFN2ADDR(v);
return (void *) PA2KA(PFN2ADDR(pfn));
return (void *) PFN2ADDR(pfn);
}
 
/** Free a frame.
*
* Find respective frame structure for supplied physical frame address.
* Decrement frame reference count.
* If it drops to zero, move the frame structure to free list.
* Decrement frame reference count. If it drops to zero, move the frame
* structure to free list.
*
* @param frame Physical Address of of the frame to be freed.
* @param frame Physical Address of of the frame to be freed.
*
*/
void frame_free(uintptr_t frame)
{
ipl_t ipl;
zone_t *zone;
pfn_t pfn = ADDR2PFN(frame);
 
ipl = interrupts_disable();
 
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
/*
* First, find host frame zone for addr.
*/
zone = find_zone_and_lock(pfn, NULL);
ASSERT(zone);
pfn_t pfn = ADDR2PFN(frame);
size_t znum = find_zone(pfn, 1, NULL);
zone_frame_free(zone, pfn - zone->base);
ASSERT(znum != (size_t) -1);
spinlock_unlock(&zone->lock);
zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base);
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
/*
* Signal that some memory has been freed.
*/
mutex_lock(&mem_avail_mtx);
mem_avail_frames++;
mem_avail_gen++;
condvar_broadcast(&mem_avail_cv);
if (mem_avail_req > 0)
mem_avail_req--;
if (mem_avail_req == 0) {
mem_avail_gen++;
condvar_broadcast(&mem_avail_cv);
}
mutex_unlock(&mem_avail_mtx);
 
interrupts_restore(ipl);
}
 
/** Add reference to frame.
1115,44 → 1123,45
* Find respective frame structure for supplied PFN and
* increment frame reference count.
*
* @param pfn Frame number of the frame to be freed.
* @param pfn Frame number of the frame to be freed.
*
*/
void frame_reference_add(pfn_t pfn)
{
ipl_t ipl;
zone_t *zone;
frame_t *frame;
 
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
/*
* First, find host frame zone for addr.
*/
zone = find_zone_and_lock(pfn, NULL);
ASSERT(zone);
size_t znum = find_zone(pfn, 1, NULL);
frame = &zone->frames[pfn - zone->base];
frame->refcount++;
ASSERT(znum != (size_t) -1);
spinlock_unlock(&zone->lock);
zones.info[znum].frames[pfn - zones.info[znum].base].refcount++;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
}
 
/** Mark given range unavailable in frame zones. */
void frame_mark_unavailable(pfn_t start, count_t count)
void frame_mark_unavailable(pfn_t start, size_t count)
{
unsigned int i;
zone_t *zone;
unsigned int prefzone = 0;
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
size_t i;
for (i = 0; i < count; i++) {
zone = find_zone_and_lock(start + i, &prefzone);
if (!zone) /* PFN not found */
size_t znum = find_zone(start + i, 1, 0);
if (znum == (size_t) -1) /* PFN not found */
continue;
zone_mark_unavailable(zone, start + i - zone->base);
 
spinlock_unlock(&zone->lock);
zone_mark_unavailable(&zones.info[znum],
start + i - zones.info[znum].base);
}
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
}
 
/** Initialize physical memory management. */
1164,6 → 1173,7
mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE);
condvar_initialize(&mem_avail_cv);
}
/* Tell the architecture to create some memory */
frame_arch_init();
if (config.cpu_active == 1) {
1172,41 → 1182,34
frame_mark_unavailable(ADDR2PFN(KA2PA(config.stack_base)),
SIZE2FRAMES(config.stack_size));
count_t i;
size_t i;
for (i = 0; i < init.cnt; i++) {
pfn_t pfn = ADDR2PFN(KA2PA(init.tasks[i].addr));
frame_mark_unavailable(pfn,
SIZE2FRAMES(init.tasks[i].size));
}
 
if (ballocs.size)
frame_mark_unavailable(ADDR2PFN(KA2PA(ballocs.base)),
SIZE2FRAMES(ballocs.size));
 
/* Black list first frame, as allocating NULL would
* fail in some places */
* fail in some places
*/
frame_mark_unavailable(0, 1);
}
}
 
 
/** Return total size of all zones. */
uint64_t zone_total_size(void)
{
zone_t *zone = NULL;
unsigned int i;
ipl_t ipl;
uint64_t total = 0;
 
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
for (i = 0; i < zones.count; i++) {
zone = zones.info[i];
spinlock_lock(&zone->lock);
total += (uint64_t) FRAMES2SIZE(zone->count);
spinlock_unlock(&zone->lock);
}
uint64_t total = 0;
size_t i;
for (i = 0; i < zones.count; i++)
total += (uint64_t) FRAMES2SIZE(zones.info[i].count);
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
1217,18 → 1220,14
/** Prints list of zones. */
void zone_print_list(void)
{
zone_t *zone = NULL;
unsigned int i;
ipl_t ipl;
 
#ifdef __32_BITS__
printf("# base address free frames busy frames\n");
printf("-- ------------ ------------ ------------\n");
#ifdef __32_BITS__
printf("# base address frames flags free frames busy frames\n");
printf("-- ------------ ------------ -------- ------------ ------------\n");
#endif
 
#ifdef __64_BITS__
printf("# base address free frames busy frames\n");
printf("-- -------------------- ------------ ------------\n");
printf("# base address frames flags free frames busy frames\n");
printf("-- -------------------- ------------ -------- ------------ ------------\n");
#endif
/*
1241,13 → 1240,10
* we may end up with inaccurate output (e.g. a zone being skipped from
* the listing).
*/
 
for (i = 0; ; i++) {
uintptr_t base;
count_t free_count;
count_t busy_count;
 
ipl = interrupts_disable();
size_t i;
for (i = 0;; i++) {
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
if (i >= zones.count) {
1255,56 → 1251,61
interrupts_restore(ipl);
break;
}
 
zone = zones.info[i];
spinlock_lock(&zone->lock);
 
base = PFN2ADDR(zone->base);
free_count = zone->free_count;
busy_count = zone->busy_count;
 
spinlock_unlock(&zone->lock);
uintptr_t base = PFN2ADDR(zones.info[i].base);
size_t count = zones.info[i].count;
zone_flags_t flags = zones.info[i].flags;
size_t free_count = zones.info[i].free_count;
size_t busy_count = zones.info[i].busy_count;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
 
bool available = zone_flags_available(flags);
printf("%-2" PRIs, i);
#ifdef __32_BITS__
printf("%-2u %10p %12" PRIc " %12" PRIc "\n", i, base,
free_count, busy_count);
printf(" %10p", base);
#endif
 
#ifdef __64_BITS__
printf("%-2u %18p %12" PRIc " %12" PRIc "\n", i, base,
free_count, busy_count);
printf(" %18p", base);
#endif
printf(" %12" PRIs " %c%c%c ", count,
available ? 'A' : ' ',
(flags & ZONE_RESERVED) ? 'R' : ' ',
(flags & ZONE_FIRMWARE) ? 'F' : ' ');
if (available)
printf("%12" PRIs " %12" PRIs,
free_count, busy_count);
printf("\n");
}
}
 
/** Prints zone details.
*
* @param num Zone base address or zone number.
* @param num Zone base address or zone number.
*
*/
void zone_print_one(unsigned int num)
void zone_print_one(size_t num)
{
zone_t *zone = NULL;
ipl_t ipl;
unsigned int i;
uintptr_t base;
count_t count;
count_t busy_count;
count_t free_count;
 
ipl = interrupts_disable();
ipl_t ipl = interrupts_disable();
spinlock_lock(&zones.lock);
 
size_t znum = (size_t) -1;
size_t i;
for (i = 0; i < zones.count; i++) {
if ((i == num) || (PFN2ADDR(zones.info[i]->base) == num)) {
zone = zones.info[i];
if ((i == num) || (PFN2ADDR(zones.info[i].base) == num)) {
znum = i;
break;
}
}
if (!zone) {
if (znum == (size_t) -1) {
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
printf("Zone not found.\n");
1311,24 → 1312,33
return;
}
spinlock_lock(&zone->lock);
base = PFN2ADDR(zone->base);
count = zone->count;
busy_count = zone->busy_count;
free_count = zone->free_count;
spinlock_unlock(&zone->lock);
uintptr_t base = PFN2ADDR(zones.info[i].base);
zone_flags_t flags = zones.info[i].flags;
size_t count = zones.info[i].count;
size_t free_count = zones.info[i].free_count;
size_t busy_count = zones.info[i].busy_count;
spinlock_unlock(&zones.lock);
interrupts_restore(ipl);
 
bool available = zone_flags_available(flags);
printf("Zone number: %" PRIs "\n", znum);
printf("Zone base address: %p\n", base);
printf("Zone size: %" PRIc " frames (%" PRIs " KiB)\n", count,
printf("Zone size: %" PRIs " frames (%" PRIs " KiB)\n", count,
SIZE2KB(FRAMES2SIZE(count)));
printf("Allocated space: %" PRIc " frames (%" PRIs " KiB)\n",
busy_count, SIZE2KB(FRAMES2SIZE(busy_count)));
printf("Available space: %" PRIc " frames (%" PRIs " KiB)\n",
free_count, SIZE2KB(FRAMES2SIZE(free_count)));
printf("Zone flags: %c%c%c\n",
available ? 'A' : ' ',
(flags & ZONE_RESERVED) ? 'R' : ' ',
(flags & ZONE_FIRMWARE) ? 'F' : ' ');
if (available) {
printf("Allocated space: %" PRIs " frames (%" PRIs " KiB)\n",
busy_count, SIZE2KB(FRAMES2SIZE(busy_count)));
printf("Available space: %" PRIs " frames (%" PRIs " KiB)\n",
free_count, SIZE2KB(FRAMES2SIZE(free_count)));
}
}
 
/** @}
*/
 
/branches/arm/kernel/generic/src/mm/backend_elf.c
82,7 → 82,7
elf_segment_header_t *entry = area->backend_data.segment;
btree_node_t *leaf;
uintptr_t base, frame, page, start_anon;
index_t i;
size_t i;
bool dirty = false;
 
if (!as_area_check_access(area, access))
129,7 → 129,7
page_mapping_insert(AS, addr, frame,
as_area_get_flags(area));
if (!used_space_insert(area, page, 1))
panic("Could not insert used space.\n");
panic("Cannot insert used space.");
mutex_unlock(&area->sh_info->lock);
return AS_PF_OK;
}
214,7 → 214,7
 
page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
if (!used_space_insert(area, page, 1))
panic("Could not insert used space.\n");
panic("Cannot insert used space.");
 
return AS_PF_OK;
}
234,7 → 234,7
elf_header_t *elf = area->backend_data.elf;
elf_segment_header_t *entry = area->backend_data.segment;
uintptr_t base, start_anon;
index_t i;
size_t i;
 
ASSERT((page >= ALIGN_DOWN(entry->p_vaddr, PAGE_SIZE)) &&
(page < entry->p_vaddr + entry->p_memsz));
304,7 → 304,7
for (i = 0; i < node->keys; i++) {
uintptr_t base = node->key[i];
count_t count = (count_t) node->value[i];
size_t count = (size_t) node->value[i];
unsigned int j;
/*
/branches/arm/kernel/generic/src/mm/buddy.c
46,7 → 46,7
#include <macros.h>
 
/** Return size needed for the buddy configuration data. */
size_t buddy_conf_size(int max_order)
size_t buddy_conf_size(size_t max_order)
{
return sizeof(buddy_system_t) + (max_order + 1) * sizeof(link_t);
}
/branches/arm/kernel/generic/src/mm/backend_phys.c
77,7 → 77,7
page_mapping_insert(AS, addr, base + (addr - area->base),
as_area_get_flags(area));
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
panic("Could not insert used space.\n");
panic("Cannot insert used space.");
 
return AS_PF_OK;
}
/branches/arm/kernel/generic/src/ipc/event.c
0,0 → 1,154
/*
* Copyright (c) 2009 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 generic
* @{
*/
/**
* @file
* @brief Kernel event notifications.
*/
 
#include <ipc/event.h>
#include <ipc/event_types.h>
#include <mm/slab.h>
#include <arch/types.h>
#include <synch/spinlock.h>
#include <console/console.h>
#include <memstr.h>
#include <errno.h>
#include <arch.h>
 
/**
* The events array.
* Arranging the events in this two-dimensional array should decrease the
* likelyhood of cacheline ping-pong.
*/
static event_t events[EVENT_END];
 
/** Initialize kernel events. */
void event_init(void)
{
unsigned int i;
for (i = 0; i < EVENT_END; i++) {
spinlock_initialize(&events[i].lock, "event.lock");
events[i].answerbox = NULL;
events[i].counter = 0;
events[i].method = 0;
}
}
 
static int event_subscribe(event_type_t evno, unative_t method,
answerbox_t *answerbox)
{
if (evno >= EVENT_END)
return ELIMIT;
spinlock_lock(&events[evno].lock);
int res;
if (events[evno].answerbox == NULL) {
events[evno].answerbox = answerbox;
events[evno].method = method;
events[evno].counter = 0;
res = EOK;
} else
res = EEXISTS;
spinlock_unlock(&events[evno].lock);
return res;
}
 
unative_t sys_event_subscribe(unative_t evno, unative_t method)
{
return (unative_t) event_subscribe((event_type_t) evno, (unative_t)
method, &TASK->answerbox);
}
 
bool event_is_subscribed(event_type_t evno)
{
bool res;
ASSERT(evno < EVENT_END);
spinlock_lock(&events[evno].lock);
res = events[evno].answerbox != NULL;
spinlock_unlock(&events[evno].lock);
return res;
}
 
 
void event_cleanup_answerbox(answerbox_t *answerbox)
{
unsigned int i;
for (i = 0; i < EVENT_END; i++) {
spinlock_lock(&events[i].lock);
if (events[i].answerbox == answerbox) {
events[i].answerbox = NULL;
events[i].counter = 0;
events[i].method = 0;
}
spinlock_unlock(&events[i].lock);
}
}
 
void event_notify(event_type_t evno, unative_t a1, unative_t a2, unative_t a3,
unative_t a4, unative_t a5)
{
ASSERT(evno < EVENT_END);
spinlock_lock(&events[evno].lock);
if (events[evno].answerbox != NULL) {
call_t *call = ipc_call_alloc(FRAME_ATOMIC);
if (call) {
call->flags |= IPC_CALL_NOTIF;
call->priv = ++events[evno].counter;
IPC_SET_METHOD(call->data, events[evno].method);
IPC_SET_ARG1(call->data, a1);
IPC_SET_ARG2(call->data, a2);
IPC_SET_ARG3(call->data, a3);
IPC_SET_ARG4(call->data, a4);
IPC_SET_ARG5(call->data, a5);
spinlock_lock(&events[evno].answerbox->irq_lock);
list_append(&call->link, &events[evno].answerbox->irq_notifs);
spinlock_unlock(&events[evno].answerbox->irq_lock);
waitq_wakeup(&events[evno].answerbox->wq, WAKEUP_FIRST);
}
}
spinlock_unlock(&events[evno].lock);
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/generic/src/ipc/sysipc.c
93,6 → 93,8
static inline int method_is_forwardable(unative_t method)
{
switch (method) {
case IPC_M_CONNECTION_CLONE:
case IPC_M_CONNECT_ME:
case IPC_M_PHONE_HUNGUP:
/* This message is meant only for the original recipient. */
return 0;
140,6 → 142,8
static inline int answer_need_old(call_t *call)
{
switch (IPC_GET_METHOD(call->data)) {
case IPC_M_CONNECTION_CLONE:
case IPC_M_CONNECT_ME:
case IPC_M_CONNECT_TO_ME:
case IPC_M_CONNECT_ME_TO:
case IPC_M_SHARE_OUT:
182,9 → 186,48
if (!olddata)
return 0;
 
if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) {
if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECTION_CLONE) {
phoneid = IPC_GET_ARG1(*olddata);
phone_t *phone = &TASK->phones[phoneid];
if (IPC_GET_RETVAL(answer->data) != EOK) {
/*
* The recipient of the cloned phone rejected the offer.
* In this case, the connection was established at the
* request time and therefore we need to slam the phone.
* We don't merely hangup as that would result in
* sending IPC_M_HUNGUP to the third party on the
* other side of the cloned phone.
*/
mutex_lock(&phone->lock);
if (phone->state == IPC_PHONE_CONNECTED) {
spinlock_lock(&phone->callee->lock);
list_remove(&phone->link);
phone->state = IPC_PHONE_SLAMMED;
spinlock_unlock(&phone->callee->lock);
}
mutex_unlock(&phone->lock);
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME) {
phone_t *phone = (phone_t *)IPC_GET_ARG5(*olddata);
if (IPC_GET_RETVAL(answer->data) != EOK) {
/*
* The other party on the cloned phoned rejected our
* request for connection on the protocol level.
* We need to break the connection without sending
* IPC_M_HUNGUP back.
*/
mutex_lock(&phone->lock);
if (phone->state == IPC_PHONE_CONNECTED) {
spinlock_lock(&phone->callee->lock);
list_remove(&phone->link);
phone->state = IPC_PHONE_SLAMMED;
spinlock_unlock(&phone->callee->lock);
}
mutex_unlock(&phone->lock);
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_TO_ME) {
phoneid = IPC_GET_ARG5(*olddata);
if (IPC_GET_RETVAL(answer->data)) {
if (IPC_GET_RETVAL(answer->data) != EOK) {
/* The connection was not accepted */
phone_dealloc(phoneid);
} else {
196,7 → 239,7
}
} else if (IPC_GET_METHOD(*olddata) == IPC_M_CONNECT_ME_TO) {
/* If the users accepted call, connect */
if (!IPC_GET_RETVAL(answer->data)) {
if (IPC_GET_RETVAL(answer->data) == EOK) {
ipc_phone_connect((phone_t *) IPC_GET_ARG5(*olddata),
&TASK->answerbox);
}
293,6 → 336,26
return 0;
}
 
static void phones_lock(phone_t *p1, phone_t *p2)
{
if (p1 < p2) {
mutex_lock(&p1->lock);
mutex_lock(&p2->lock);
} else if (p1 > p2) {
mutex_lock(&p2->lock);
mutex_lock(&p1->lock);
} else {
mutex_lock(&p1->lock);
}
}
 
static void phones_unlock(phone_t *p1, phone_t *p2)
{
mutex_unlock(&p1->lock);
if (p1 != p2)
mutex_unlock(&p2->lock);
}
 
/** Called before the request is sent.
*
* @param call Call structure with the request.
308,8 → 371,39
int rc;
 
switch (IPC_GET_METHOD(call->data)) {
case IPC_M_CONNECTION_CLONE: {
phone_t *cloned_phone;
GET_CHECK_PHONE(cloned_phone, IPC_GET_ARG1(call->data),
return ENOENT);
phones_lock(cloned_phone, phone);
if ((cloned_phone->state != IPC_PHONE_CONNECTED) ||
phone->state != IPC_PHONE_CONNECTED) {
phones_unlock(cloned_phone, phone);
return EINVAL;
}
/*
* We can be pretty sure now that both tasks exist and we are
* connected to them. As we continue to hold the phone locks,
* we are effectively preventing them from finishing their
* potential cleanup.
*/
newphid = phone_alloc(phone->callee->task);
if (newphid < 0) {
phones_unlock(cloned_phone, phone);
return ELIMIT;
}
ipc_phone_connect(&phone->callee->task->phones[newphid],
cloned_phone->callee);
phones_unlock(cloned_phone, phone);
/* Set the new phone for the callee. */
IPC_SET_ARG1(call->data, newphid);
break;
}
case IPC_M_CONNECT_ME:
IPC_SET_ARG5(call->data, (unative_t) phone);
break;
case IPC_M_CONNECT_ME_TO:
newphid = phone_alloc();
newphid = phone_alloc(TASK);
if (newphid < 0)
return ELIMIT;
/* Set arg5 for server */
332,7 → 426,7
src = IPC_GET_ARG1(call->data);
size = IPC_GET_ARG2(call->data);
if ((size <= 0) || (size > DATA_XFER_LIMIT))
if (size > DATA_XFER_LIMIT)
return ELIMIT;
call->buffer = (uint8_t *) malloc(size, 0);
399,7 → 493,7
int phoneid;
 
if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) {
phoneid = phone_alloc();
phoneid = phone_alloc(TASK);
if (phoneid < 0) { /* Failed to allocate phone */
IPC_SET_RETVAL(call->data, ELIMIT);
ipc_answer(box, call);
455,10 → 549,17
IPC_SET_ARG5(call.data, 0);
 
if (!(res = request_preprocess(&call, phone))) {
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
rc = ipc_call_sync(phone, &call);
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
if (rc != EOK)
return rc;
process_answer(&call);
 
} else {
IPC_SET_RETVAL(call.data, res);
}
495,7 → 596,13
GET_CHECK_PHONE(phone, phoneid, return ENOENT);
 
if (!(res = request_preprocess(&call, phone))) {
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
rc = ipc_call_sync(phone, &call);
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
if (rc != EOK)
return rc;
process_answer(&call);
605,7 → 712,8
return (unative_t) call;
}
 
/** Forward a received call to another destination.
/** Forward a received call to another destination - common code for both the
* fast and the slow version.
*
* @param callid Hash of the call to forward.
* @param phoneid Phone handle to use for forwarding.
612,23 → 720,21
* @param method New method to use for the forwarded call.
* @param arg1 New value of the first argument for the forwarded call.
* @param arg2 New value of the second argument for the forwarded call.
* @param arg3 New value of the third argument for the forwarded call.
* @param arg4 New value of the fourth argument for the forwarded call.
* @param arg5 New value of the fifth argument for the forwarded call.
* @param mode Flags that specify mode of the forward operation.
* @param slow If true, arg3, arg4 and arg5 are considered. Otherwise
* the function considers only the fast version arguments:
* i.e. arg1 and arg2.
*
* @return Return 0 on succes, otherwise return an error code.
*
* In case the original method is a system method, ARG1, ARG2 and ARG3 are
* overwritten in the forwarded message with the new method and the new arg1 and
* arg2, respectively. Otherwise the METHOD, ARG1 and ARG2 are rewritten with
* the new method, arg1 and arg2, respectively. Also note there is a set of
* immutable methods, for which the new method and argument is not set and
* these values are ignored.
*
* Warning: When implementing support for changing additional payload
* arguments, make sure that ARG5 is not rewritten for certain
* system IPC
* Warning: Make sure that ARG5 is not rewritten for certain system IPC
*/
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1, unative_t arg2, int mode)
static unative_t sys_ipc_forward_common(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1, unative_t arg2, unative_t arg3,
unative_t arg4, unative_t arg5, int mode, bool slow)
{
call_t *call;
phone_t *phone;
636,7 → 742,7
call = get_call(callid);
if (!call)
return ENOENT;
 
call->flags |= IPC_CALL_FORWARDED;
 
GET_CHECK_PHONE(phone, phoneid, {
653,8 → 759,8
 
/*
* Userspace is not allowed to change method of system methods on
* forward, allow changing ARG1, ARG2 and ARG3 by means of method,
* arg1 and arg2.
* forward, allow changing ARG1, ARG2, ARG3 and ARG4 by means of method,
* arg1, arg2 and arg3.
* If the method is immutable, don't change anything.
*/
if (!method_is_immutable(IPC_GET_METHOD(call->data))) {
665,10 → 771,22
IPC_SET_ARG1(call->data, method);
IPC_SET_ARG2(call->data, arg1);
IPC_SET_ARG3(call->data, arg2);
if (slow) {
IPC_SET_ARG4(call->data, arg3);
/*
* For system methods we deliberately don't
* overwrite ARG5.
*/
}
} else {
IPC_SET_METHOD(call->data, method);
IPC_SET_ARG1(call->data, arg1);
IPC_SET_ARG2(call->data, arg2);
if (slow) {
IPC_SET_ARG3(call->data, arg3);
IPC_SET_ARG4(call->data, arg4);
IPC_SET_ARG5(call->data, arg5);
}
}
}
 
675,6 → 793,64
return ipc_forward(call, phone, &TASK->answerbox, mode);
}
 
/** Forward a received call to another destination - fast version.
*
* @param callid Hash of the call to forward.
* @param phoneid Phone handle to use for forwarding.
* @param method New method to use for the forwarded call.
* @param arg1 New value of the first argument for the forwarded call.
* @param arg2 New value of the second argument for the forwarded call.
* @param mode Flags that specify mode of the forward operation.
*
* @return Return 0 on succes, otherwise return an error code.
*
* In case the original method is a system method, ARG1, ARG2 and ARG3 are
* overwritten in the forwarded message with the new method and the new
* arg1 and arg2, respectively. Otherwise the METHOD, ARG1 and ARG2 are
* rewritten with the new method, arg1 and arg2, respectively. Also note there
* is a set of immutable methods, for which the new method and arguments are not
* set and these values are ignored.
*/
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid,
unative_t method, unative_t arg1, unative_t arg2, int mode)
{
return sys_ipc_forward_common(callid, phoneid, method, arg1, arg2, 0, 0,
0, mode, false);
}
 
/** Forward a received call to another destination - slow version.
*
* @param callid Hash of the call to forward.
* @param phoneid Phone handle to use for forwarding.
* @param data Userspace address of the new IPC data.
* @param mode Flags that specify mode of the forward operation.
*
* @return Return 0 on succes, otherwise return an error code.
*
* This function is the slow verision of the sys_ipc_forward_fast interface.
* It can copy all five new arguments and the new method from the userspace.
* It naturally extends the functionality of the fast version. For system
* methods, it additionally stores the new value of arg3 to ARG4. For non-system
* methods, it additionally stores the new value of arg3, arg4 and arg5,
* respectively, to ARG3, ARG4 and ARG5, respectively.
*/
unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid,
ipc_data_t *data, int mode)
{
ipc_data_t newdata;
int rc;
 
rc = copy_from_uspace(&newdata.args, &data->args,
sizeof(newdata.args));
if (rc != 0)
return (unative_t) rc;
 
return sys_ipc_forward_common(callid, phoneid,
IPC_GET_METHOD(newdata), IPC_GET_ARG1(newdata),
IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata),
IPC_GET_ARG4(newdata), IPC_GET_ARG5(newdata), mode, true);
}
 
/** Answer an IPC call - fast version.
*
* This function can handle only two return arguments of payload, but is faster
798,9 → 974,17
{
call_t *call;
 
restart:
restart:
 
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
#endif
call = ipc_wait_for_call(&TASK->answerbox, usec,
flags | SYNCH_FLAGS_INTERRUPTIBLE);
 
#ifdef CONFIG_UDEBUG
udebug_stoppable_end();
#endif
if (!call)
return 0;
 
846,6 → 1030,21
/* Include phone address('id') of the caller in the request,
* copy whole call->data, not only call->data.args */
if (STRUCT_TO_USPACE(calldata, &call->data)) {
/*
* The callee will not receive this call and no one else has
* a chance to answer it. Reply with the EPARTY error code.
*/
ipc_data_t saved_data;
int saveddata = 0;
 
if (answer_need_old(call)) {
memcpy(&saved_data, &call->data, sizeof(call->data));
saveddata = 1;
}
IPC_SET_RETVAL(call->data, EPARTY);
(void) answer_preprocess(call, saveddata ? &saved_data : NULL);
ipc_answer(&TASK->answerbox, call);
return 0;
}
return (unative_t)call;
/branches/arm/kernel/generic/src/ipc/ipcrsc.c
160,27 → 160,29
return result;
}
 
/** Allocate new phone slot in the current TASK structure.
/** Allocate new phone slot in the specified task.
*
* @param t Task for which to allocate a new phone.
*
* @return New phone handle or -1 if the phone handle limit is
* exceeded.
*/
int phone_alloc(void)
int phone_alloc(task_t *t)
{
int i;
 
spinlock_lock(&TASK->lock);
spinlock_lock(&t->lock);
for (i = 0; i < IPC_MAX_PHONES; i++) {
if (TASK->phones[i].state == IPC_PHONE_HUNGUP &&
atomic_get(&TASK->phones[i].active_calls) == 0)
TASK->phones[i].state = IPC_PHONE_FREE;
if (t->phones[i].state == IPC_PHONE_HUNGUP &&
atomic_get(&t->phones[i].active_calls) == 0)
t->phones[i].state = IPC_PHONE_FREE;
 
if (TASK->phones[i].state == IPC_PHONE_FREE) {
TASK->phones[i].state = IPC_PHONE_CONNECTING;
if (t->phones[i].state == IPC_PHONE_FREE) {
t->phones[i].state = IPC_PHONE_CONNECTING;
break;
}
}
spinlock_unlock(&TASK->lock);
spinlock_unlock(&t->lock);
 
if (i == IPC_MAX_PHONES)
return -1;
/branches/arm/kernel/generic/src/ipc/kbox.c
42,19 → 42,27
#include <debug.h>
#include <udebug/udebug_ipc.h>
#include <ipc/kbox.h>
#include <print.h>
 
void ipc_kbox_cleanup(void)
{
ipl_t ipl;
bool have_kb_thread;
 
/* Only hold kb_cleanup_lock while setting kb_finished - this is enough */
mutex_lock(&TASK->kb_cleanup_lock);
TASK->kb_finished = true;
mutex_unlock(&TASK->kb_cleanup_lock);
/*
* Only hold kb.cleanup_lock while setting kb.finished -
* this is enough.
*/
mutex_lock(&TASK->kb.cleanup_lock);
TASK->kb.finished = true;
mutex_unlock(&TASK->kb.cleanup_lock);
 
have_kb_thread = (TASK->kb_thread != NULL);
have_kb_thread = (TASK->kb.thread != NULL);
 
/* From now on nobody will try to connect phones or attach kbox threads */
/*
* From now on nobody will try to connect phones or attach
* kbox threads
*/
 
/*
* Disconnect all phones connected to our kbox. Passing true for
62,83 → 70,136
* disconnected phone. This ensures the kbox thread is going to
* wake up and terminate.
*/
ipc_answerbox_slam_phones(&TASK->kernel_box, have_kb_thread);
ipc_answerbox_slam_phones(&TASK->kb.box, have_kb_thread);
 
/*
* If the task was being debugged, clean up debugging session.
* This is necessarry as slamming the phones won't force
* kbox thread to clean it up since sender != debugger.
*/
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
udebug_task_cleanup(TASK);
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
if (have_kb_thread) {
LOG("join kb_thread..\n");
thread_join(TASK->kb_thread);
thread_detach(TASK->kb_thread);
LOG("join done\n");
TASK->kb_thread = NULL;
LOG("Join kb.thread.");
thread_join(TASK->kb.thread);
thread_detach(TASK->kb.thread);
LOG("...join done.");
TASK->kb.thread = NULL;
}
 
/* Answer all messages in 'calls' and 'dispatched_calls' queues */
spinlock_lock(&TASK->kernel_box.lock);
ipc_cleanup_call_list(&TASK->kernel_box.dispatched_calls);
ipc_cleanup_call_list(&TASK->kernel_box.calls);
spinlock_unlock(&TASK->kernel_box.lock);
/* Answer all messages in 'calls' and 'dispatched_calls' queues. */
spinlock_lock(&TASK->kb.box.lock);
ipc_cleanup_call_list(&TASK->kb.box.dispatched_calls);
ipc_cleanup_call_list(&TASK->kb.box.calls);
spinlock_unlock(&TASK->kb.box.lock);
}
 
/** Handle hangup message in kbox.
*
* @param call The IPC_M_PHONE_HUNGUP call structure.
* @param last Output, the function stores @c true here if
* this was the last phone, @c false otherwise.
**/
static void kbox_proc_phone_hungup(call_t *call, bool *last)
{
ipl_t ipl;
 
/* Was it our debugger, who hung up? */
if (call->sender == TASK->udebug.debugger) {
/* Terminate debugging session (if any). */
LOG("Terminate debugging session.");
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
udebug_task_cleanup(TASK);
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
} else {
LOG("Was not debugger.");
}
 
LOG("Continue with hangup message.");
IPC_SET_RETVAL(call->data, 0);
ipc_answer(&TASK->kb.box, call);
 
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
spinlock_lock(&TASK->kb.box.lock);
if (list_empty(&TASK->kb.box.connected_phones)) {
/*
* Last phone has been disconnected. Detach this thread so it
* gets freed and signal to the caller.
*/
 
/* Only detach kbox thread unless already terminating. */
mutex_lock(&TASK->kb.cleanup_lock);
if (&TASK->kb.finished == false) {
/* Detach kbox thread so it gets freed from memory. */
thread_detach(TASK->kb.thread);
TASK->kb.thread = NULL;
}
mutex_unlock(&TASK->kb.cleanup_lock);
 
LOG("Phone list is empty.");
*last = true;
} else {
*last = false;
}
 
spinlock_unlock(&TASK->kb.box.lock);
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
}
 
/** Implementing function for the kbox thread.
*
* This function listens for debug requests. It terminates
* when all phones are disconnected from the kbox.
*
* @param arg Ignored.
*/
static void kbox_thread_proc(void *arg)
{
call_t *call;
int method;
bool done;
ipl_t ipl;
 
(void)arg;
LOG("kbox_thread_proc()\n");
LOG("Starting.");
done = false;
 
while (!done) {
call = ipc_wait_for_call(&TASK->kernel_box, SYNCH_NO_TIMEOUT,
call = ipc_wait_for_call(&TASK->kb.box, SYNCH_NO_TIMEOUT,
SYNCH_FLAGS_NONE);
 
if (call != NULL) {
method = IPC_GET_METHOD(call->data);
if (call == NULL)
continue; /* Try again. */
 
if (method == IPC_M_DEBUG_ALL) {
udebug_call_receive(call);
}
switch (IPC_GET_METHOD(call->data)) {
 
if (method == IPC_M_PHONE_HUNGUP) {
LOG("kbox: handle hangup message\n");
case IPC_M_DEBUG_ALL:
/* Handle debug call. */
udebug_call_receive(call);
break;
 
/* Was it our debugger, who hung up? */
if (call->sender == TASK->udebug.debugger) {
/* Terminate debugging session (if any) */
LOG("kbox: terminate debug session\n");
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
udebug_task_cleanup(TASK);
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
} else {
LOG("kbox: was not debugger\n");
}
case IPC_M_PHONE_HUNGUP:
/*
* Process the hangup call. If this was the last
* phone, done will be set to true and the
* while loop will terminate.
*/
kbox_proc_phone_hungup(call, &done);
break;
 
LOG("kbox: continue with hangup message\n");
IPC_SET_RETVAL(call->data, 0);
ipc_answer(&TASK->kernel_box, call);
 
ipl = interrupts_disable();
spinlock_lock(&TASK->lock);
spinlock_lock(&TASK->answerbox.lock);
if (list_empty(&TASK->answerbox.connected_phones)) {
/* Last phone has been disconnected */
TASK->kb_thread = NULL;
done = true;
LOG("phone list is empty\n");
}
spinlock_unlock(&TASK->answerbox.lock);
spinlock_unlock(&TASK->lock);
interrupts_restore(ipl);
}
default:
/* Ignore */
break;
}
}
 
LOG("kbox: finished\n");
LOG("Exiting.");
}
 
 
145,10 → 206,10
/**
* Connect phone to a task kernel-box specified by id.
*
* Note that this is not completely atomic. For optimisation reasons,
* The task might start cleaning up kbox after the phone has been connected
* and before a kbox thread has been created. This must be taken into account
* in the cleanup code.
* Note that this is not completely atomic. For optimisation reasons, the task
* might start cleaning up kbox after the phone has been connected and before
* a kbox thread has been created. This must be taken into account in the
* cleanup code.
*
* @return Phone id on success, or negative error code.
*/
174,44 → 235,45
spinlock_unlock(&tasks_lock);
interrupts_restore(ipl);
 
mutex_lock(&ta->kb_cleanup_lock);
mutex_lock(&ta->kb.cleanup_lock);
 
if (atomic_predec(&ta->refcount) == 0) {
mutex_unlock(&ta->kb_cleanup_lock);
mutex_unlock(&ta->kb.cleanup_lock);
task_destroy(ta);
return ENOENT;
}
 
if (ta->kb_finished != false) {
mutex_unlock(&ta->kb_cleanup_lock);
if (ta->kb.finished != false) {
mutex_unlock(&ta->kb.cleanup_lock);
return EINVAL;
}
 
newphid = phone_alloc();
newphid = phone_alloc(TASK);
if (newphid < 0) {
mutex_unlock(&ta->kb_cleanup_lock);
mutex_unlock(&ta->kb.cleanup_lock);
return ELIMIT;
}
 
/* Connect the newly allocated phone to the kbox */
ipc_phone_connect(&TASK->phones[newphid], &ta->kernel_box);
ipc_phone_connect(&TASK->phones[newphid], &ta->kb.box);
 
if (ta->kb_thread != NULL) {
mutex_unlock(&ta->kb_cleanup_lock);
if (ta->kb.thread != NULL) {
mutex_unlock(&ta->kb.cleanup_lock);
return newphid;
}
 
/* Create a kbox thread */
kb_thread = thread_create(kbox_thread_proc, NULL, ta, 0, "kbox", false);
kb_thread = thread_create(kbox_thread_proc, NULL, ta, 0,
"kbox", false);
if (!kb_thread) {
mutex_unlock(&ta->kb_cleanup_lock);
mutex_unlock(&ta->kb.cleanup_lock);
return ENOMEM;
}
 
ta->kb_thread = kb_thread;
ta->kb.thread = kb_thread;
thread_ready(kb_thread);
 
mutex_unlock(&ta->kb_cleanup_lock);
mutex_unlock(&ta->kb.cleanup_lock);
 
return newphid;
}
/branches/arm/kernel/generic/src/ipc/ipc.c
44,6 → 44,7
#include <synch/synch.h>
#include <ipc/ipc.h>
#include <ipc/kbox.h>
#include <ipc/event.h>
#include <errno.h>
#include <mm/slab.h>
#include <arch.h>
50,7 → 51,6
#include <proc/task.h>
#include <memstr.h>
#include <debug.h>
 
#include <print.h>
#include <console/console.h>
#include <proc/thread.h>
328,12 → 328,10
list_remove(&phone->link);
spinlock_unlock(&box->lock);
 
if (phone->state != IPC_PHONE_SLAMMED) {
call = ipc_call_alloc(0);
IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP);
call->flags |= IPC_CALL_DISCARD_ANSWER;
_ipc_call(phone, box, call);
}
call = ipc_call_alloc(0);
IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP);
call->flags |= IPC_CALL_DISCARD_ANSWER;
_ipc_call(phone, box, call);
}
 
phone->state = IPC_PHONE_HUNGUP;
526,6 → 524,9
for (i = 0; i < IPC_MAX_PHONES; i++)
ipc_phone_hangup(&TASK->phones[i]);
 
/* Unsubscribe from any event notifications. */
event_cleanup_answerbox(&TASK->answerbox);
 
/* Disconnect all connected irqs */
ipc_irq_cleanup(&TASK->answerbox);
 
/branches/arm/kernel/generic/src/ipc/irq.c
44,8 → 44,28
* - ARG1: payload modified by a 'top-half' handler
* - ARG2: payload modified by a 'top-half' handler
* - ARG3: payload modified by a 'top-half' handler
* - ARG4: payload modified by a 'top-half' handler
* - ARG5: payload modified by a 'top-half' handler
* - in_phone_hash: interrupt counter (may be needed to assure correct order
* in multithreaded drivers)
*
* Note on synchronization for ipc_irq_register(), ipc_irq_unregister(),
* ipc_irq_cleanup() and IRQ handlers:
*
* By always taking all of the uspace IRQ hash table lock, IRQ structure lock
* and answerbox lock, we can rule out race conditions between the
* registration functions and also the cleanup function. Thus the observer can
* either see the IRQ structure present in both the hash table and the
* answerbox list or absent in both. Views in which the IRQ structure would be
* linked in the hash table but not in the answerbox list, or vice versa, are
* not possible.
*
* By always taking the hash table lock and the IRQ structure lock, we can
* rule out a scenario in which we would free up an IRQ structure, which is
* still referenced by, for example, an IRQ handler. The locking scheme forces
* us to lock the IRQ structure only after any progressing IRQs on that
* structure are finished. Because we hold the hash table lock, we prevent new
* IRQs from taking new references to the IRQ structure.
*/
 
#include <arch.h>
58,78 → 78,8
#include <console/console.h>
#include <print.h>
 
/** Execute code associated with IRQ notification.
/** Free the top-half pseudocode.
*
* @param call Notification call.
* @param code Top-half pseudocode.
*/
static void code_execute(call_t *call, irq_code_t *code)
{
unsigned int i;
unative_t dstval = 0;
if (!code)
return;
for (i = 0; i < code->cmdcount; i++) {
switch (code->cmds[i].cmd) {
case CMD_MEM_READ_1:
dstval = *((uint8_t *) code->cmds[i].addr);
break;
case CMD_MEM_READ_2:
dstval = *((uint16_t *) code->cmds[i].addr);
break;
case CMD_MEM_READ_4:
dstval = *((uint32_t *) code->cmds[i].addr);
break;
case CMD_MEM_READ_8:
dstval = *((uint64_t *) code->cmds[i].addr);
break;
case CMD_MEM_WRITE_1:
*((uint8_t *) code->cmds[i].addr) = code->cmds[i].value;
break;
case CMD_MEM_WRITE_2:
*((uint16_t *) code->cmds[i].addr) =
code->cmds[i].value;
break;
case CMD_MEM_WRITE_4:
*((uint32_t *) code->cmds[i].addr) =
code->cmds[i].value;
break;
case CMD_MEM_WRITE_8:
*((uint64_t *) code->cmds[i].addr) =
code->cmds[i].value;
break;
#if defined(ia32) || defined(amd64)
case CMD_PORT_READ_1:
dstval = inb((long) code->cmds[i].addr);
break;
case CMD_PORT_WRITE_1:
outb((long) code->cmds[i].addr, code->cmds[i].value);
break;
#endif
#if defined(ia64) && defined(SKI)
case CMD_IA64_GETCHAR:
dstval = _getc(&ski_uconsole);
break;
#endif
#if defined(ppc32)
case CMD_PPC32_GETCHAR:
dstval = cuda_get_scancode();
break;
#endif
default:
break;
}
if (code->cmds[i].dstarg && code->cmds[i].dstarg <
IPC_CALL_LEN) {
call->data.args[code->cmds[i].dstarg] = dstval;
}
}
}
 
/** Free top-half pseudocode.
*
* @param code Pointer to the top-half pseudocode.
*/
static void code_free(irq_code_t *code)
140,7 → 90,7
}
}
 
/** Copy top-half pseudocode from userspace into the kernel.
/** Copy the top-half pseudocode from userspace into the kernel.
*
* @param ucode Userspace address of the top-half pseudocode.
*
176,47 → 126,16
return code;
}
 
/** Unregister task from IRQ notification.
*
* @param box Answerbox associated with the notification.
* @param inr IRQ number.
* @param devno Device number.
*/
void ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno)
{
ipl_t ipl;
irq_t *irq;
 
ipl = interrupts_disable();
irq = irq_find_and_lock(inr, devno);
if (irq) {
if (irq->notif_cfg.answerbox == box) {
code_free(irq->notif_cfg.code);
irq->notif_cfg.notify = false;
irq->notif_cfg.answerbox = NULL;
irq->notif_cfg.code = NULL;
irq->notif_cfg.method = 0;
irq->notif_cfg.counter = 0;
 
spinlock_lock(&box->irq_lock);
list_remove(&irq->notif_cfg.link);
spinlock_unlock(&box->irq_lock);
spinlock_unlock(&irq->lock);
}
}
interrupts_restore(ipl);
}
 
/** Register an answerbox as a receiving end for IRQ notifications.
*
* @param box Receiving answerbox.
* @param inr IRQ number.
* @param devno Device number.
* @param method Method to be associated with the notification.
* @param ucode Uspace pointer to top-half pseudocode.
* @param box Receiving answerbox.
* @param inr IRQ number.
* @param devno Device number.
* @param method Method to be associated with the notification.
* @param ucode Uspace pointer to top-half pseudocode.
*
* @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success.
* @return EBADMEM, ENOENT or EEXISTS on failure or 0 on success.
*
*/
int ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno,
unative_t method, irq_code_t *ucode)
224,7 → 143,12
ipl_t ipl;
irq_code_t *code;
irq_t *irq;
 
link_t *hlp;
unative_t key[] = {
(unative_t) inr,
(unative_t) devno
};
if (ucode) {
code = code_from_uspace(ucode);
if (!code)
232,36 → 156,177
} else {
code = NULL;
}
 
/*
* Allocate and populate the IRQ structure.
*/
irq = malloc(sizeof(irq_t), 0);
irq_initialize(irq);
irq->devno = devno;
irq->inr = inr;
irq->claim = ipc_irq_top_half_claim;
irq->handler = ipc_irq_top_half_handler;
irq->notif_cfg.notify = true;
irq->notif_cfg.answerbox = box;
irq->notif_cfg.method = method;
irq->notif_cfg.code = code;
irq->notif_cfg.counter = 0;
/*
* Enlist the IRQ structure in the uspace IRQ hash table and the
* answerbox's list.
*/
ipl = interrupts_disable();
irq = irq_find_and_lock(inr, devno);
if (!irq) {
interrupts_restore(ipl);
spinlock_lock(&irq_uspace_hash_table_lock);
hlp = hash_table_find(&irq_uspace_hash_table, key);
if (hlp) {
irq_t *hirq __attribute__((unused))
= hash_table_get_instance(hlp, irq_t, link);
/* hirq is locked */
spinlock_unlock(&hirq->lock);
code_free(code);
return ENOENT;
}
if (irq->notif_cfg.answerbox) {
spinlock_unlock(&irq->lock);
spinlock_unlock(&irq_uspace_hash_table_lock);
free(irq);
interrupts_restore(ipl);
code_free(code);
return EEXISTS;
}
irq->notif_cfg.notify = true;
irq->notif_cfg.answerbox = box;
irq->notif_cfg.method = method;
irq->notif_cfg.code = code;
irq->notif_cfg.counter = 0;
 
spinlock_lock(&irq->lock); /* Not really necessary, but paranoid */
spinlock_lock(&box->irq_lock);
hash_table_insert(&irq_uspace_hash_table, key, &irq->link);
list_append(&irq->notif_cfg.link, &box->irq_head);
spinlock_unlock(&box->irq_lock);
spinlock_unlock(&irq->lock);
spinlock_unlock(&irq_uspace_hash_table_lock);
interrupts_restore(ipl);
return EOK;
}
 
/** Unregister task from IRQ notification.
*
* @param box Answerbox associated with the notification.
* @param inr IRQ number.
* @param devno Device number.
*/
int ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno)
{
ipl_t ipl;
unative_t key[] = {
(unative_t) inr,
(unative_t) devno
};
link_t *lnk;
irq_t *irq;
 
ipl = interrupts_disable();
spinlock_lock(&irq_uspace_hash_table_lock);
lnk = hash_table_find(&irq_uspace_hash_table, key);
if (!lnk) {
spinlock_unlock(&irq_uspace_hash_table_lock);
interrupts_restore(ipl);
return ENOENT;
}
irq = hash_table_get_instance(lnk, irq_t, link);
/* irq is locked */
spinlock_lock(&box->irq_lock);
ASSERT(irq->notif_cfg.answerbox == box);
/* Free up the pseudo code and associated structures. */
code_free(irq->notif_cfg.code);
 
/* Remove the IRQ from the answerbox's list. */
list_remove(&irq->notif_cfg.link);
 
/*
* We need to drop the IRQ lock now because hash_table_remove() will try
* to reacquire it. That basically violates the natural locking order,
* but a deadlock in hash_table_remove() is prevented by the fact that
* we already held the IRQ lock and didn't drop the hash table lock in
* the meantime.
*/
spinlock_unlock(&irq->lock);
 
/* Remove the IRQ from the uspace IRQ hash table. */
hash_table_remove(&irq_uspace_hash_table, key, 2);
spinlock_unlock(&irq_uspace_hash_table_lock);
spinlock_unlock(&box->irq_lock);
/* Free up the IRQ structure. */
free(irq);
interrupts_restore(ipl);
return EOK;
}
 
return 0;
 
/** Disconnect all IRQ notifications from an answerbox.
*
* This function is effective because the answerbox contains
* list of all irq_t structures that are registered to
* send notifications to it.
*
* @param box Answerbox for which we want to carry out the cleanup.
*/
void ipc_irq_cleanup(answerbox_t *box)
{
ipl_t ipl;
loop:
ipl = interrupts_disable();
spinlock_lock(&irq_uspace_hash_table_lock);
spinlock_lock(&box->irq_lock);
while (box->irq_head.next != &box->irq_head) {
link_t *cur = box->irq_head.next;
irq_t *irq;
DEADLOCK_PROBE_INIT(p_irqlock);
unative_t key[2];
irq = list_get_instance(cur, irq_t, notif_cfg.link);
if (!spinlock_trylock(&irq->lock)) {
/*
* Avoid deadlock by trying again.
*/
spinlock_unlock(&box->irq_lock);
spinlock_unlock(&irq_uspace_hash_table_lock);
interrupts_restore(ipl);
DEADLOCK_PROBE(p_irqlock, DEADLOCK_THRESHOLD);
goto loop;
}
key[0] = irq->inr;
key[1] = irq->devno;
ASSERT(irq->notif_cfg.answerbox == box);
/* Unlist from the answerbox. */
list_remove(&irq->notif_cfg.link);
/* Free up the pseudo code and associated structures. */
code_free(irq->notif_cfg.code);
/*
* We need to drop the IRQ lock now because hash_table_remove()
* will try to reacquire it. That basically violates the natural
* locking order, but a deadlock in hash_table_remove() is
* prevented by the fact that we already held the IRQ lock and
* didn't drop the hash table lock in the meantime.
*/
spinlock_unlock(&irq->lock);
/* Remove from the hash table. */
hash_table_remove(&irq_uspace_hash_table, key, 2);
free(irq);
}
spinlock_unlock(&box->irq_lock);
spinlock_unlock(&irq_uspace_hash_table_lock);
interrupts_restore(ipl);
}
 
/** Add a call to the proper answerbox queue.
280,125 → 345,158
waitq_wakeup(&irq->notif_cfg.answerbox->wq, WAKEUP_FIRST);
}
 
/** Send notification message.
/** Apply the top-half pseudo code to find out whether to accept the IRQ or not.
*
* @param irq IRQ structure.
* @param a1 Driver-specific payload argument.
* @param a2 Driver-specific payload argument.
* @param a3 Driver-specific payload argument.
* @param a4 Driver-specific payload argument.
* @param a5 Driver-specific payload argument.
*
* @return IRQ_ACCEPT if the interrupt is accepted by the
* pseudocode. IRQ_DECLINE otherwise.
*/
void ipc_irq_send_msg(irq_t *irq, unative_t a1, unative_t a2, unative_t a3,
unative_t a4, unative_t a5)
irq_ownership_t ipc_irq_top_half_claim(irq_t *irq)
{
call_t *call;
unsigned int i;
unative_t dstval;
irq_code_t *code = irq->notif_cfg.code;
unative_t *scratch = irq->notif_cfg.scratch;
 
spinlock_lock(&irq->lock);
 
if (irq->notif_cfg.answerbox) {
call = ipc_call_alloc(FRAME_ATOMIC);
if (!call) {
spinlock_unlock(&irq->lock);
return;
if (!irq->notif_cfg.notify)
return IRQ_DECLINE;
if (!code)
return IRQ_DECLINE;
for (i = 0; i < code->cmdcount; i++) {
unsigned int srcarg = code->cmds[i].srcarg;
unsigned int dstarg = code->cmds[i].dstarg;
if (srcarg >= IPC_CALL_LEN)
break;
if (dstarg >= IPC_CALL_LEN)
break;
switch (code->cmds[i].cmd) {
case CMD_PIO_READ_8:
dstval = pio_read_8((ioport8_t *) code->cmds[i].addr);
if (dstarg)
scratch[dstarg] = dstval;
break;
case CMD_PIO_READ_16:
dstval = pio_read_16((ioport16_t *) code->cmds[i].addr);
if (dstarg)
scratch[dstarg] = dstval;
break;
case CMD_PIO_READ_32:
dstval = pio_read_32((ioport32_t *) code->cmds[i].addr);
if (dstarg)
scratch[dstarg] = dstval;
break;
case CMD_PIO_WRITE_8:
pio_write_8((ioport8_t *) code->cmds[i].addr,
(uint8_t) code->cmds[i].value);
break;
case CMD_PIO_WRITE_16:
pio_write_16((ioport16_t *) code->cmds[i].addr,
(uint16_t) code->cmds[i].value);
break;
case CMD_PIO_WRITE_32:
pio_write_32((ioport32_t *) code->cmds[i].addr,
(uint32_t) code->cmds[i].value);
break;
case CMD_BTEST:
if (srcarg && dstarg) {
dstval = scratch[srcarg] & code->cmds[i].value;
scratch[dstarg] = dstval;
}
break;
case CMD_PREDICATE:
if (srcarg && !scratch[srcarg]) {
i += code->cmds[i].value;
continue;
}
break;
case CMD_ACCEPT:
return IRQ_ACCEPT;
break;
case CMD_DECLINE:
default:
return IRQ_DECLINE;
}
call->flags |= IPC_CALL_NOTIF;
IPC_SET_METHOD(call->data, irq->notif_cfg.method);
IPC_SET_ARG1(call->data, a1);
IPC_SET_ARG2(call->data, a2);
IPC_SET_ARG3(call->data, a3);
IPC_SET_ARG4(call->data, a4);
IPC_SET_ARG5(call->data, a5);
/* Put a counter to the message */
call->priv = ++irq->notif_cfg.counter;
send_call(irq, call);
}
spinlock_unlock(&irq->lock);
return IRQ_DECLINE;
}
 
/** Notify a task that an IRQ had occurred.
 
/* IRQ top-half handler.
*
* We expect interrupts to be disabled and the irq->lock already held.
*
* @param irq IRQ structure.
*/
void ipc_irq_send_notif(irq_t *irq)
void ipc_irq_top_half_handler(irq_t *irq)
{
call_t *call;
 
ASSERT(irq);
 
if (irq->notif_cfg.answerbox) {
call_t *call;
 
call = ipc_call_alloc(FRAME_ATOMIC);
if (!call) {
if (!call)
return;
}
call->flags |= IPC_CALL_NOTIF;
/* Put a counter to the message */
call->priv = ++irq->notif_cfg.counter;
 
/* Set up args */
IPC_SET_METHOD(call->data, irq->notif_cfg.method);
IPC_SET_ARG1(call->data, irq->notif_cfg.scratch[1]);
IPC_SET_ARG2(call->data, irq->notif_cfg.scratch[2]);
IPC_SET_ARG3(call->data, irq->notif_cfg.scratch[3]);
IPC_SET_ARG4(call->data, irq->notif_cfg.scratch[4]);
IPC_SET_ARG5(call->data, irq->notif_cfg.scratch[5]);
 
/* Execute code to handle irq */
code_execute(call, irq->notif_cfg.code);
send_call(irq, call);
}
}
 
/** Disconnect all IRQ notifications from an answerbox.
/** Send notification message.
*
* This function is effective because the answerbox contains
* list of all irq_t structures that are registered to
* send notifications to it.
*
* @param box Answerbox for which we want to carry out the cleanup.
* @param irq IRQ structure.
* @param a1 Driver-specific payload argument.
* @param a2 Driver-specific payload argument.
* @param a3 Driver-specific payload argument.
* @param a4 Driver-specific payload argument.
* @param a5 Driver-specific payload argument.
*/
void ipc_irq_cleanup(answerbox_t *box)
void ipc_irq_send_msg(irq_t *irq, unative_t a1, unative_t a2, unative_t a3,
unative_t a4, unative_t a5)
{
ipl_t ipl;
loop:
ipl = interrupts_disable();
spinlock_lock(&box->irq_lock);
while (box->irq_head.next != &box->irq_head) {
link_t *cur = box->irq_head.next;
irq_t *irq;
DEADLOCK_PROBE_INIT(p_irqlock);
irq = list_get_instance(cur, irq_t, notif_cfg.link);
if (!spinlock_trylock(&irq->lock)) {
/*
* Avoid deadlock by trying again.
*/
spinlock_unlock(&box->irq_lock);
interrupts_restore(ipl);
DEADLOCK_PROBE(p_irqlock, DEADLOCK_THRESHOLD);
goto loop;
call_t *call;
 
spinlock_lock(&irq->lock);
 
if (irq->notif_cfg.answerbox) {
call = ipc_call_alloc(FRAME_ATOMIC);
if (!call) {
spinlock_unlock(&irq->lock);
return;
}
call->flags |= IPC_CALL_NOTIF;
/* Put a counter to the message */
call->priv = ++irq->notif_cfg.counter;
 
IPC_SET_METHOD(call->data, irq->notif_cfg.method);
IPC_SET_ARG1(call->data, a1);
IPC_SET_ARG2(call->data, a2);
IPC_SET_ARG3(call->data, a3);
IPC_SET_ARG4(call->data, a4);
IPC_SET_ARG5(call->data, a5);
ASSERT(irq->notif_cfg.answerbox == box);
list_remove(&irq->notif_cfg.link);
/*
* Don't forget to free any top-half pseudocode.
*/
code_free(irq->notif_cfg.code);
irq->notif_cfg.notify = false;
irq->notif_cfg.answerbox = NULL;
irq->notif_cfg.code = NULL;
irq->notif_cfg.method = 0;
irq->notif_cfg.counter = 0;
 
spinlock_unlock(&irq->lock);
send_call(irq, call);
}
spinlock_unlock(&box->irq_lock);
interrupts_restore(ipl);
spinlock_unlock(&irq->lock);
}
 
/** @}
/branches/arm/kernel/generic/src/syscall/syscall.c
32,9 → 32,9
 
/**
* @file
* @brief Syscall table and syscall wrappers.
* @brief Syscall table and syscall wrappers.
*/
 
#include <syscall/syscall.h>
#include <proc/thread.h>
#include <proc/task.h>
41,61 → 41,19
#include <proc/program.h>
#include <mm/as.h>
#include <print.h>
#include <putchar.h>
#include <errno.h>
#include <arch.h>
#include <debug.h>
#include <ddi/device.h>
#include <ipc/sysipc.h>
#include <synch/futex.h>
#include <synch/smc.h>
#include <ddi/ddi.h>
#include <ipc/event.h>
#include <security/cap.h>
#include <syscall/copy.h>
#include <sysinfo/sysinfo.h>
#include <console/console.h>
#include <udebug/udebug.h>
 
/** Print using kernel facility
*
* Print to kernel log.
*
*/
static unative_t sys_klog(int fd, const void * buf, size_t count)
{
size_t i;
char *data;
int rc;
 
if (count > PAGE_SIZE)
return ELIMIT;
if (count > 0) {
data = (char *) malloc(count, 0);
if (!data)
return ENOMEM;
rc = copy_from_uspace(data, buf, count);
if (rc) {
free(data);
return rc;
}
for (i = 0; i < count; i++)
putchar(data[i]);
free(data);
} else
klog_update();
return count;
}
 
/** Tell kernel to get keyboard/console access again */
static unative_t sys_debug_enable_console(void)
{
arch_grab_console();
return 0;
}
 
/** Dispatch system call */
unative_t syscall_handler(unative_t a1, unative_t a2, unative_t a3,
unative_t a4, unative_t a5, unative_t a6, unative_t id)
103,13 → 61,20
unative_t rc;
 
#ifdef CONFIG_UDEBUG
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
#endif
bool debug;
 
if (id < SYSCALL_END) {
#ifdef CONFIG_UDEBUG
udebug_stoppable_begin();
/*
* Early check for undebugged tasks. We do not lock anything as this
* test need not be precise in either way.
*/
debug = THREAD->udebug.active;
if (debug) {
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false);
}
#endif
if (id < SYSCALL_END) {
rc = syscall_table[id](a1, a2, a3, a4, a5, a6);
} else {
printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id);
116,13 → 81,22
task_kill(TASK->taskid);
thread_exit();
}
if (THREAD->interrupted)
thread_exit();
 
#ifdef CONFIG_UDEBUG
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
udebug_stoppable_end();
if (debug) {
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true);
/*
* Stopping point needed for tasks that only invoke
* non-blocking system calls. Not needed if the task
* is not being debugged (it cannot block here).
*/
udebug_stoppable_begin();
udebug_stoppable_end();
}
#endif
return rc;
138,6 → 112,7
(syshandler_t) sys_thread_get_id,
(syshandler_t) sys_task_get_id,
(syshandler_t) sys_task_set_name,
(syshandler_t) sys_program_spawn_loader,
/* Synchronization related syscalls. */
159,10 → 134,14
(syshandler_t) sys_ipc_answer_fast,
(syshandler_t) sys_ipc_answer_slow,
(syshandler_t) sys_ipc_forward_fast,
(syshandler_t) sys_ipc_forward_slow,
(syshandler_t) sys_ipc_wait_for_call,
(syshandler_t) sys_ipc_hangup,
(syshandler_t) sys_ipc_register_irq,
(syshandler_t) sys_ipc_unregister_irq,
 
/* Event notification syscalls. */
(syshandler_t) sys_event_subscribe,
/* Capabilities related syscalls. */
(syshandler_t) sys_cap_grant,
169,6 → 148,7
(syshandler_t) sys_cap_revoke,
/* DDI related syscalls. */
(syshandler_t) sys_device_assign_devno,
(syshandler_t) sys_physmem_map,
(syshandler_t) sys_iospace_enable,
(syshandler_t) sys_preempt_control,
179,7 → 159,8
/* Debug calls */
(syshandler_t) sys_debug_enable_console,
 
(syshandler_t) sys_debug_disable_console,
(syshandler_t) sys_ipc_connect_kbox
};
 
/branches/arm/kernel/generic/src/udebug/udebug.c
35,18 → 35,6
* @brief Udebug hooks and data structure management.
*
* Udebug is an interface that makes userspace debuggers possible.
*
* Functions in this file are executed directly in each thread, which
* may or may not be the subject of debugging. The udebug_stoppable_begin/end()
* functions are also executed in the clock interrupt handler. To avoid
* deadlock, functions in this file are protected from the interrupt
* by locking the recursive lock THREAD->udebug.int_lock (just an atomic
* variable). This prevents udebug_stoppable_begin/end() from being
* executed in the interrupt handler (they are skipped).
*
* Functions in udebug_ops.c and udebug_ipc.c execute in different threads,
* so they needn't be protected from the (preemptible) interrupt-initiated
* code.
*/
#include <synch/waitq.h>
53,18 → 41,10
#include <debug.h>
#include <udebug/udebug.h>
#include <errno.h>
#include <print.h>
#include <arch.h>
 
static inline void udebug_int_lock(void)
{
atomic_inc(&THREAD->udebug.int_lock);
}
 
static inline void udebug_int_unlock(void)
{
atomic_dec(&THREAD->udebug.int_lock);
}
 
/** Initialize udebug part of task structure.
*
* Called as part of task structure initialization.
89,15 → 69,11
mutex_initialize(&ut->lock, MUTEX_PASSIVE);
waitq_initialize(&ut->go_wq);
 
/*
* At the beginning the thread is stoppable, so int_lock be set, too.
*/
atomic_set(&ut->int_lock, 1);
 
ut->go_call = NULL;
ut->stop = true;
ut->uspace_state = NULL;
ut->go = false;
ut->stoppable = true;
ut->debug_active = false;
ut->active = false;
ut->cur_event = 0; /* none */
}
 
122,27 → 98,6
waitq_sleep_finish(wq, rc, ipl);
}
 
/** Do a preliminary check that a debugging session is in progress.
*
* This only requires the THREAD->udebug.lock mutex (and not TASK->udebug.lock
* mutex). For an undebugged task, this will never block (while there could be
* collisions by different threads on the TASK mutex), thus improving SMP
* perormance for undebugged tasks.
*
* @return True if the thread was in a debugging session when the function
* checked, false otherwise.
*/
static bool udebug_thread_precheck(void)
{
bool res;
 
mutex_lock(&THREAD->udebug.lock);
res = THREAD->udebug.debug_active;
mutex_unlock(&THREAD->udebug.lock);
 
return res;
}
 
/** Start of stoppable section.
*
* A stoppable section is a section of code where if the thread can be stoped. In other words,
161,14 → 116,6
ASSERT(THREAD);
ASSERT(TASK);
 
udebug_int_lock();
 
/* Early check for undebugged tasks */
if (!udebug_thread_precheck()) {
udebug_int_unlock();
return;
}
 
mutex_lock(&TASK->udebug.lock);
 
nsc = --TASK->udebug.not_stoppable_count;
198,7 → 145,8
* Active debugging session
*/
 
if (THREAD->udebug.debug_active && THREAD->udebug.stop) {
if (THREAD->udebug.active == true &&
THREAD->udebug.go == false) {
/*
* Thread was requested to stop - answer go call
*/
228,18 → 176,11
*/
void udebug_stoppable_end(void)
{
/* Early check for undebugged tasks */
if (!udebug_thread_precheck()) {
udebug_int_unlock();
return;
}
 
restart:
mutex_lock(&TASK->udebug.lock);
mutex_lock(&THREAD->udebug.lock);
 
if (THREAD->udebug.debug_active &&
THREAD->udebug.stop == true) {
if (THREAD->udebug.active && THREAD->udebug.go == false) {
TASK->udebug.begin_call = NULL;
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
247,7 → 188,7
udebug_wait_for_go(&THREAD->udebug.go_wq);
 
goto restart;
/* must try again - have to lose stoppability atomically */
/* Must try again - have to lose stoppability atomically. */
} else {
++TASK->udebug.not_stoppable_count;
ASSERT(THREAD->udebug.stoppable == true);
256,44 → 197,17
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
}
 
udebug_int_unlock();
}
 
/** Upon being scheduled to run, check if the current thread should stop.
*
* This function is called from clock(). Preemption is enabled.
* interrupts are disabled, but since this is called after
* being scheduled-in, we can enable them, if we're careful enough
* not to allow arbitrary recursion or deadlock with the thread context.
* This function is called from clock().
*/
void udebug_before_thread_runs(void)
{
ipl_t ipl;
 
return;
ASSERT(!PREEMPTION_DISABLED);
 
/*
* Prevent agains re-entering, such as when preempted inside this
* function.
*/
if (atomic_get(&THREAD->udebug.int_lock) != 0)
return;
 
udebug_int_lock();
 
ipl = interrupts_enable();
 
/* Now we're free to do whatever we need (lock mutexes, sleep, etc.) */
 
/* Check if we're supposed to stop */
udebug_stoppable_begin();
udebug_stoppable_end();
 
interrupts_restore(ipl);
 
udebug_int_unlock();
}
 
/** Syscall event hook.
310,20 → 224,11
 
etype = end_variant ? UDEBUG_EVENT_SYSCALL_E : UDEBUG_EVENT_SYSCALL_B;
 
udebug_int_lock();
 
/* Early check for undebugged tasks */
if (!udebug_thread_precheck()) {
udebug_int_unlock();
return;
}
 
mutex_lock(&TASK->udebug.lock);
mutex_lock(&THREAD->udebug.lock);
 
/* Must only generate events when in debugging session and have go */
if (THREAD->udebug.debug_active != true ||
THREAD->udebug.stop == true ||
/* Must only generate events when in debugging session and is go. */
if (THREAD->udebug.active != true || THREAD->udebug.go == false ||
(TASK->udebug.evmask & UDEBUG_EVMASK(etype)) == 0) {
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
330,7 → 235,7
return;
}
 
//printf("udebug_syscall_event\n");
/* Fill in the GO response. */
call = THREAD->udebug.go_call;
THREAD->udebug.go_call = NULL;
 
338,7 → 243,6
IPC_SET_ARG1(call->data, etype);
IPC_SET_ARG2(call->data, id);
IPC_SET_ARG3(call->data, rc);
//printf("udebug_syscall_event/ipc_answer\n");
 
THREAD->udebug.syscall_args[0] = a1;
THREAD->udebug.syscall_args[1] = a2;
348,11 → 252,11
THREAD->udebug.syscall_args[5] = a6;
 
/*
* Make sure udebug.stop is true when going to sleep
* Make sure udebug.go is false when going to sleep
* in case we get woken up by DEBUG_END. (At which
* point it must be back to the initial true value).
*/
THREAD->udebug.stop = true;
THREAD->udebug.go = false;
THREAD->udebug.cur_event = etype;
 
ipc_answer(&TASK->answerbox, call);
361,42 → 265,46
mutex_unlock(&TASK->udebug.lock);
 
udebug_wait_for_go(&THREAD->udebug.go_wq);
 
udebug_int_unlock();
}
 
/** Thread-creation event hook.
/** Thread-creation event hook combined with attaching the thread.
*
* Must be called when a new userspace thread is created in the debugged
* task. Generates a THREAD_B event.
* task. Generates a THREAD_B event. Also attaches the thread @a t
* to the task @a ta.
*
* This is necessary to avoid a race condition where the BEGIN and THREAD_READ
* requests would be handled inbetween attaching the thread and checking it
* for being in a debugging session to send the THREAD_B event. We could then
* either miss threads or get some threads both in the thread list
* and get a THREAD_B event for them.
*
* @param t Structure of the thread being created. Not locked, as the
* thread is not executing yet.
* @param ta Task to which the thread should be attached.
*/
void udebug_thread_b_event(struct thread *t)
void udebug_thread_b_event_attach(struct thread *t, struct task *ta)
{
call_t *call;
 
udebug_int_lock();
 
mutex_lock(&TASK->udebug.lock);
mutex_lock(&THREAD->udebug.lock);
 
LOG("udebug_thread_b_event\n");
LOG("- check state\n");
thread_attach(t, ta);
 
LOG("Check state");
 
/* Must only generate events when in debugging session */
if (THREAD->udebug.debug_active != true) {
LOG("- debug_active: %s, udebug.stop: %s\n",
THREAD->udebug.debug_active ? "yes(+)" : "no(-)",
THREAD->udebug.stop ? "yes(-)" : "no(+)");
if (THREAD->udebug.active != true) {
LOG("udebug.active: %s, udebug.go: %s",
THREAD->udebug.active ? "Yes(+)" : "No",
THREAD->udebug.go ? "Yes(-)" : "No");
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
return;
}
 
LOG("- trigger event\n");
 
LOG("Trigger event");
call = THREAD->udebug.go_call;
THREAD->udebug.go_call = NULL;
IPC_SET_RETVAL(call->data, 0);
404,11 → 312,11
IPC_SET_ARG2(call->data, (unative_t)t);
 
/*
* Make sure udebug.stop is true when going to sleep
* Make sure udebug.go is false when going to sleep
* in case we get woken up by DEBUG_END. (At which
* point it must be back to the initial true value).
*/
THREAD->udebug.stop = true;
THREAD->udebug.go = false;
THREAD->udebug.cur_event = UDEBUG_EVENT_THREAD_B;
 
ipc_answer(&TASK->answerbox, call);
416,10 → 324,8
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
 
LOG("- sleep\n");
LOG("Wait for Go");
udebug_wait_for_go(&THREAD->udebug.go_wq);
 
udebug_int_unlock();
}
 
/** Thread-termination event hook.
431,35 → 337,31
{
call_t *call;
 
udebug_int_lock();
 
mutex_lock(&TASK->udebug.lock);
mutex_lock(&THREAD->udebug.lock);
 
LOG("udebug_thread_e_event\n");
LOG("- check state\n");
LOG("Check state");
 
/* Must only generate events when in debugging session */
if (THREAD->udebug.debug_active != true) {
/* printf("- debug_active: %s, udebug.stop: %s\n",
THREAD->udebug.debug_active ? "yes(+)" : "no(-)",
THREAD->udebug.stop ? "yes(-)" : "no(+)");*/
/* Must only generate events when in debugging session. */
if (THREAD->udebug.active != true) {
LOG("udebug.active: %s, udebug.go: %s",
THREAD->udebug.active ? "Yes" : "No",
THREAD->udebug.go ? "Yes" : "No");
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
return;
}
 
LOG("- trigger event\n");
 
LOG("Trigger event");
call = THREAD->udebug.go_call;
THREAD->udebug.go_call = NULL;
IPC_SET_RETVAL(call->data, 0);
IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_E);
 
/* Prevent any further debug activity in thread */
THREAD->udebug.debug_active = false;
/* Prevent any further debug activity in thread. */
THREAD->udebug.active = false;
THREAD->udebug.cur_event = 0; /* none */
THREAD->udebug.stop = true; /* set to initial value */
THREAD->udebug.go = false; /* set to initial value */
 
ipc_answer(&TASK->answerbox, call);
 
466,8 → 368,10
mutex_unlock(&THREAD->udebug.lock);
mutex_unlock(&TASK->udebug.lock);
 
/* Leave int_lock enabled */
/* This event does not sleep - debugging has finished in this thread */
/*
* This event does not sleep - debugging has finished
* in this thread.
*/
}
 
/**
487,17 → 391,13
int flags;
ipl_t ipl;
 
LOG("udebug_task_cleanup()\n");
LOG("task %" PRIu64 "\n", ta->taskid);
 
udebug_int_lock();
 
if (ta->udebug.dt_state != UDEBUG_TS_BEGINNING &&
ta->udebug.dt_state != UDEBUG_TS_ACTIVE) {
LOG("udebug_task_cleanup(): task not being debugged\n");
return EINVAL;
}
 
LOG("Task %" PRIu64, ta->taskid);
 
/* Finish debugging of all userspace threads */
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) {
t = list_get_instance(cur, thread_t, th_link);
512,22 → 412,22
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
 
/* Only process userspace threads */
/* Only process userspace threads. */
if ((flags & THREAD_FLAG_USPACE) != 0) {
/* Prevent any further debug activity in thread */
t->udebug.debug_active = false;
/* Prevent any further debug activity in thread. */
t->udebug.active = false;
t->udebug.cur_event = 0; /* none */
 
/* Still has go? */
if (t->udebug.stop == false) {
/* Is the thread still go? */
if (t->udebug.go == true) {
/*
* Yes, so clear go. As debug_active == false,
* Yes, so clear go. As active == false,
* this doesn't affect anything.
*/
t->udebug.stop = true;
t->udebug.go = false;
 
/* Answer GO call */
LOG("answer GO call with EVENT_FINISHED\n");
LOG("Answer GO call with EVENT_FINISHED.");
IPC_SET_RETVAL(t->udebug.go_call->data, 0);
IPC_SET_ARG1(t->udebug.go_call->data,
UDEBUG_EVENT_FINISHED);
553,8 → 453,6
ta->udebug.dt_state = UDEBUG_TS_INACTIVE;
ta->udebug.debugger = NULL;
 
udebug_int_unlock();
 
return 0;
}
 
/branches/arm/kernel/generic/src/udebug/udebug_ops.c
44,6 → 44,7
#include <proc/thread.h>
#include <arch.h>
#include <errno.h>
#include <print.h>
#include <syscall/copy.h>
#include <ipc/ipc.h>
#include <udebug/udebug.h>
57,8 → 58,8
*
* Specifically, verifies that thread t exists, is a userspace thread,
* and belongs to the current task (TASK). Verifies, that the thread
* has (or hasn't) go according to having_go (typically false).
* It also locks t->udebug.lock, making sure that t->udebug.debug_active
* is (or is not) go according to being_go (typically false).
* It also locks t->udebug.lock, making sure that t->udebug.active
* is true - that the thread is in a valid debugging session.
*
* With this verified and the t->udebug.lock mutex held, it is ensured
70,11 → 71,11
* the t->lock spinlock to the t->udebug.lock mutex.
*
* @param t Pointer, need not at all be valid.
* @param having_go Required thread state.
* @param being_go Required thread state.
*
* Returns EOK if all went well, or an error code otherwise.
*/
static int _thread_op_begin(thread_t *t, bool having_go)
static int _thread_op_begin(thread_t *t, bool being_go)
{
task_id_t taskid;
ipl_t ipl;
98,7 → 99,7
spinlock_lock(&t->lock);
spinlock_unlock(&threads_lock);
 
/* Verify that 't' is a userspace thread */
/* Verify that 't' is a userspace thread. */
if ((t->flags & THREAD_FLAG_USPACE) == 0) {
/* It's not, deny its existence */
spinlock_unlock(&t->lock);
107,8 → 108,8
return ENOENT;
}
 
/* Verify debugging state */
if (t->udebug.debug_active != true) {
/* Verify debugging state. */
if (t->udebug.active != true) {
/* Not in debugging session or undesired GO state */
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
117,16 → 118,16
}
 
/*
* Since the thread has debug_active == true, TASK->udebug.lock
* is enough to ensure its existence and that debug_active remains
* Since the thread has active == true, TASK->udebug.lock
* is enough to ensure its existence and that active remains
* true.
*/
spinlock_unlock(&t->lock);
interrupts_restore(ipl);
 
/* Only mutex TASK->udebug.lock left */
/* Only mutex TASK->udebug.lock left. */
/* Now verify that the thread belongs to the current task */
/* Now verify that the thread belongs to the current task. */
if (t->task != TASK) {
/* No such thread belonging this task*/
mutex_unlock(&TASK->udebug.lock);
139,18 → 140,18
*/
mutex_lock(&t->udebug.lock);
 
/* The big task mutex is no longer needed */
/* The big task mutex is no longer needed. */
mutex_unlock(&TASK->udebug.lock);
 
if (!t->udebug.stop != having_go) {
/* Not in debugging session or undesired GO state */
if (t->udebug.go != being_go) {
/* Not in debugging session or undesired GO state. */
mutex_unlock(&t->udebug.lock);
return EINVAL;
}
 
/* Only t->udebug.lock left */
/* Only t->udebug.lock left. */
 
return EOK; /* All went well */
return EOK; /* All went well. */
}
 
/** End debugging operation on a thread. */
180,15 → 181,11
thread_t *t;
link_t *cur;
 
LOG("udebug_begin()\n");
 
LOG("Debugging task %llu", TASK->taskid);
mutex_lock(&TASK->udebug.lock);
LOG("debugging task %llu\n", TASK->taskid);
 
if (TASK->udebug.dt_state != UDEBUG_TS_INACTIVE) {
mutex_unlock(&TASK->udebug.lock);
LOG("udebug_begin(): busy error\n");
 
return EBUSY;
}
 
204,7 → 201,7
reply = 0; /* no reply */
}
/* Set udebug.debug_active on all of the task's userspace threads */
/* Set udebug.active on all of the task's userspace threads. */
 
for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) {
t = list_get_instance(cur, thread_t, th_link);
211,15 → 208,11
 
mutex_lock(&t->udebug.lock);
if ((t->flags & THREAD_FLAG_USPACE) != 0)
t->udebug.debug_active = true;
t->udebug.active = true;
mutex_unlock(&t->udebug.lock);
}
 
mutex_unlock(&TASK->udebug.lock);
 
LOG("udebug_begin() done (%s)\n",
reply ? "reply" : "stoppability wait");
 
return reply;
}
 
232,13 → 225,10
{
int rc;
 
LOG("udebug_end()\n");
LOG("Task %" PRIu64, TASK->taskid);
 
mutex_lock(&TASK->udebug.lock);
LOG("task %" PRIu64 "\n", TASK->taskid);
 
rc = udebug_task_cleanup(TASK);
 
mutex_unlock(&TASK->udebug.lock);
 
return rc;
253,19 → 243,16
*/
int udebug_set_evmask(udebug_evmask_t mask)
{
LOG("udebug_set_mask()\n");
LOG("mask = 0x%x", mask);
 
mutex_lock(&TASK->udebug.lock);
 
if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) {
mutex_unlock(&TASK->udebug.lock);
LOG("udebug_set_mask(): not active debuging session\n");
 
return EINVAL;
}
 
TASK->udebug.evmask = mask;
 
mutex_unlock(&TASK->udebug.lock);
 
return 0;
273,7 → 260,7
 
/** Give thread GO.
*
* Upon recieving a go message, the thread is given GO. Having GO
* Upon recieving a go message, the thread is given GO. Being GO
* means the thread is allowed to execute userspace code (until
* a debugging event or STOP occurs, at which point the thread loses GO.
*
284,7 → 271,7
{
int rc;
 
/* On success, this will lock t->udebug.lock */
/* On success, this will lock t->udebug.lock. */
rc = _thread_op_begin(t, false);
if (rc != EOK) {
return rc;
291,11 → 278,11
}
 
t->udebug.go_call = call;
t->udebug.stop = false;
t->udebug.go = true;
t->udebug.cur_event = 0; /* none */
 
/*
* Neither t's lock nor threads_lock may be held during wakeup
* Neither t's lock nor threads_lock may be held during wakeup.
*/
waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST);
 
316,8 → 303,7
{
int rc;
 
LOG("udebug_stop()\n");
mutex_lock(&TASK->udebug.lock);
LOG("udebug_stop()");
 
/*
* On success, this will lock t->udebug.lock. Note that this makes sure
328,36 → 314,34
return rc;
}
 
/* Take GO away from the thread */
t->udebug.stop = true;
/* Take GO away from the thread. */
t->udebug.go = false;
 
if (!t->udebug.stoppable) {
/* Answer will be sent when the thread becomes stoppable */
if (t->udebug.stoppable != true) {
/* Answer will be sent when the thread becomes stoppable. */
_thread_op_end(t);
return 0;
}
 
/*
* Answer GO call
* Answer GO call.
*/
LOG("udebug_stop - answering go call\n");
 
/* Make sure nobody takes this call away from us */
/* Make sure nobody takes this call away from us. */
call = t->udebug.go_call;
t->udebug.go_call = NULL;
 
IPC_SET_RETVAL(call->data, 0);
IPC_SET_ARG1(call->data, UDEBUG_EVENT_STOP);
LOG("udebug_stop/ipc_answer\n");
 
THREAD->udebug.cur_event = UDEBUG_EVENT_STOP;
 
_thread_op_end(t);
 
mutex_lock(&TASK->udebug.lock);
ipc_answer(&TASK->answerbox, call);
mutex_unlock(&TASK->udebug.lock);
 
LOG("udebog_stop/done\n");
return 0;
}
 
391,7 → 375,7
int flags;
size_t max_ids;
 
LOG("udebug_thread_read()\n");
LOG("udebug_thread_read()");
 
/* Allocate a buffer to hold thread IDs */
id_buffer = malloc(buf_size, 0);
422,7 → 406,7
flags = t->flags;
spinlock_unlock(&t->lock);
 
/* Not interested in kernel threads */
/* Not interested in kernel threads. */
if ((flags & THREAD_FLAG_USPACE) != 0) {
/* Using thread struct pointer as identification hash */
tid = (unative_t) t;
458,16 → 442,16
int rc;
unative_t *arg_buffer;
 
/* Prepare a buffer to hold the arguments */
/* Prepare a buffer to hold the arguments. */
arg_buffer = malloc(6 * sizeof(unative_t), 0);
 
/* On success, this will lock t->udebug.lock */
/* On success, this will lock t->udebug.lock. */
rc = _thread_op_begin(t, false);
if (rc != EOK) {
return rc;
}
 
/* Additionally we need to verify that we are inside a syscall */
/* Additionally we need to verify that we are inside a syscall. */
if (t->udebug.cur_event != UDEBUG_EVENT_SYSCALL_B &&
t->udebug.cur_event != UDEBUG_EVENT_SYSCALL_E) {
_thread_op_end(t);
474,7 → 458,7
return EINVAL;
}
 
/* Copy to a local buffer before releasing the lock */
/* Copy to a local buffer before releasing the lock. */
memcpy(arg_buffer, t->udebug.syscall_args, 6 * sizeof(unative_t));
 
_thread_op_end(t);
/branches/arm/kernel/generic/src/udebug/udebug_ipc.c
73,7 → 73,7
rc = udebug_begin(call);
if (rc < 0) {
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
 
83,7 → 83,7
*/
if (rc != 0) {
IPC_SET_RETVAL(call->data, 0);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
}
 
99,7 → 99,7
rc = udebug_end();
 
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
/** Process a SET_EVMASK call.
116,7 → 116,7
rc = udebug_set_evmask(mask);
 
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
 
135,7 → 135,7
rc = udebug_go(t, call);
if (rc < 0) {
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
}
154,7 → 154,7
 
rc = udebug_stop(t, call);
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
/** Process a THREAD_READ call.
182,7 → 182,7
rc = udebug_thread_read(&buffer, buf_size, &n);
if (rc < 0) {
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
 
209,7 → 209,7
IPC_SET_ARG3(call->data, total_bytes);
call->buffer = buffer;
 
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
/** Process an ARGS_READ call.
229,7 → 229,7
rc = udebug_args_read(t, &buffer);
if (rc != EOK) {
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
 
247,7 → 247,7
IPC_SET_ARG2(call->data, 6 * sizeof(unative_t));
call->buffer = buffer;
 
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
/** Process an MEM_READ call.
270,7 → 270,7
rc = udebug_mem_read(uspace_src, size, &buffer);
if (rc < 0) {
IPC_SET_RETVAL(call->data, rc);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
 
282,7 → 282,7
IPC_SET_ARG2(call->data, size);
call->buffer = buffer;
 
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
}
 
/** Handle a debug call received on the kernel answerbox.
306,7 → 306,7
*/
if (TASK->udebug.debugger != call->sender) {
IPC_SET_RETVAL(call->data, EINVAL);
ipc_answer(&TASK->kernel_box, call);
ipc_answer(&TASK->kb.box, call);
return;
}
}
/branches/arm/kernel/generic/src/interrupt/interrupt.c
42,7 → 42,6
#include <debug.h>
#include <console/kconsole.h>
#include <console/console.h>
#include <console/chardev.h>
#include <console/cmd.h>
#include <panic.h>
#include <print.h>
68,13 → 67,13
iroutine old;
spinlock_lock(&exctbl_lock);
 
old = exc_table[n].f;
exc_table[n].f = f;
exc_table[n].name = name;
 
spinlock_unlock(&exctbl_lock);
 
spinlock_unlock(&exctbl_lock);
return old;
}
 
86,8 → 85,17
void exc_dispatch(int n, istate_t *istate)
{
ASSERT(n < IVT_ITEMS);
 
#ifdef CONFIG_UDEBUG
if (THREAD) THREAD->udebug.uspace_state = istate;
#endif
exc_table[n].f(n + IVT_FIRST, istate);
 
#ifdef CONFIG_UDEBUG
if (THREAD) THREAD->udebug.uspace_state = NULL;
#endif
 
/* This is a safe place to exit exiting thread */
if (THREAD && THREAD->interrupted && istate_from_uspace(istate))
thread_exit();
100,8 → 108,10
panic("Unhandled exception %d.", n);
}
 
#ifdef CONFIG_KCONSOLE
 
/** kconsole cmd - print all exceptions */
static int exc_print_cmd(cmd_arg_t *argv)
static int cmd_exc_print(cmd_arg_t *argv)
{
#if (IVT_ITEMS > 0)
unsigned int i;
120,9 → 130,7
#endif
for (i = 0; i < IVT_ITEMS; i++) {
symbol = get_symtab_entry((unative_t) exc_table[i].f);
if (!symbol)
symbol = "not found";
symbol = symtab_fmt_name_lookup((unative_t) exc_table[i].f);
 
#ifdef __32_BITS__
printf("%-3u %-20s %10p %s\n", i + IVT_FIRST, exc_table[i].name,
137,7 → 145,7
if (((i + 1) % 20) == 0) {
printf(" -- Press any key to continue -- ");
spinlock_unlock(&exctbl_lock);
getc(stdin);
indev_pop_character(stdin);
spinlock_lock(&exctbl_lock);
printf("\n");
}
149,15 → 157,18
return 1;
}
 
 
static cmd_info_t exc_info = {
.name = "exc",
.description = "Print exception table.",
.func = exc_print_cmd,
.func = cmd_exc_print,
.help = NULL,
.argc = 0,
.argv = NULL
};
 
#endif
 
/** Initialize generic exception handling support */
void exc_init(void)
{
166,9 → 177,11
for (i = 0; i < IVT_ITEMS; i++)
exc_register(i, "undef", (iroutine) exc_undef);
 
#ifdef CONFIG_KCONSOLE
cmd_initialize(&exc_info);
if (!cmd_register(&exc_info))
panic("could not register command %s\n", exc_info.name);
printf("Cannot register command %s\n", exc_info.name);
#endif
}
 
/** @}
/branches/arm/kernel/generic/src/cpu/cpu.c
64,7 → 64,7
cpus = (cpu_t *) malloc(sizeof(cpu_t) * config.cpu_count,
FRAME_ATOMIC);
if (!cpus)
panic("malloc/cpus");
panic("Cannot allocate CPU structures.");
 
/* initialize everything */
memsetb(cpus, sizeof(cpu_t) * config.cpu_count, 0);
86,7 → 86,7
}
#endif /* CONFIG_SMP */
 
CPU = &cpus[config.cpu_active-1];
CPU = &cpus[config.cpu_active - 1];
CPU->active = 1;
CPU->tlb_active = 1;
/branches/arm/kernel/generic/src/sysinfo/sysinfo.c
163,7 → 163,8
i = 0;
}
}
panic("Not reached\n");
 
panic("Not reached.");
return NULL;
}
 
/branches/arm/kernel/genarch/include/kbd/pl050.h
File deleted
/branches/arm/kernel/genarch/include/kbd/ns16550.h
File deleted
/branches/arm/kernel/genarch/include/kbd/i8042.h
File deleted
/branches/arm/kernel/genarch/include/kbd/scanc.h
File deleted
/branches/arm/kernel/genarch/include/kbd/scanc_pl050.h
File deleted
/branches/arm/kernel/genarch/include/kbd/key.h
File deleted
/branches/arm/kernel/genarch/include/kbd/scanc_pc.h
File deleted
/branches/arm/kernel/genarch/include/kbd/z8530.h
File deleted
/branches/arm/kernel/genarch/include/kbd/scanc_sun.h
File deleted
/branches/arm/kernel/genarch/include/drivers/via-cuda/cuda.h
0,0 → 1,123
/*
* Copyright (c) 2006 Martin Decky
* 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 genarch
* @{
*/
/** @file
*/
 
#ifndef KERN_CUDA_H_
#define KERN_CUDA_H_
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
#include <synch/spinlock.h>
 
typedef struct {
uint8_t b;
uint8_t pad0[0x1ff];
 
uint8_t a;
uint8_t pad1[0x1ff];
 
uint8_t dirb;
uint8_t pad2[0x1ff];
 
uint8_t dira;
uint8_t pad3[0x1ff];
 
uint8_t t1cl;
uint8_t pad4[0x1ff];
 
uint8_t t1ch;
uint8_t pad5[0x1ff];
 
uint8_t t1ll;
uint8_t pad6[0x1ff];
 
uint8_t t1lh;
uint8_t pad7[0x1ff];
 
uint8_t t2cl;
uint8_t pad8[0x1ff];
 
uint8_t t2ch;
uint8_t pad9[0x1ff];
 
uint8_t sr;
uint8_t pad10[0x1ff];
 
uint8_t acr;
uint8_t pad11[0x1ff];
 
uint8_t pcr;
uint8_t pad12[0x1ff];
 
uint8_t ifr;
uint8_t pad13[0x1ff];
 
uint8_t ier;
uint8_t pad14[0x1ff];
 
uint8_t anh;
uint8_t pad15[0x1ff];
} cuda_t;
 
enum {
CUDA_RCV_BUF_SIZE = 5
};
 
enum cuda_xfer_state {
cx_listen,
cx_receive,
cx_rcv_end,
cx_send_start,
cx_send
};
 
typedef struct {
irq_t irq;
cuda_t *cuda;
indev_t *kbrdin;
uint8_t rcv_buf[CUDA_RCV_BUF_SIZE];
uint8_t snd_buf[CUDA_RCV_BUF_SIZE];
size_t bidx;
size_t snd_bytes;
enum cuda_xfer_state xstate;
SPINLOCK_DECLARE(dev_lock);
} cuda_instance_t;
 
extern cuda_instance_t *cuda_init(cuda_t *, inr_t, cir_t, void *);
extern void cuda_wire(cuda_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/drivers/ns16550/ns16550.h
0,0 → 1,76
/*
* Copyright (c) 2001-2004 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 genarch
* @{
*/
/**
* @file
* @brief Headers for NS 16550 serial controller.
*/
 
#ifndef KERN_NS16550_H_
#define KERN_NS16550_H_
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
 
#define IER_ERBFI 0x01 /** Enable Receive Buffer Full Interrupt. */
 
#define LCR_DLAB 0x80 /** Divisor Latch Access bit. */
 
#define MCR_OUT2 0x08 /** OUT2. */
 
/** NS16550 registers. */
typedef struct {
ioport8_t rbr; /**< Receiver Buffer Register. */
ioport8_t ier; /**< Interrupt Enable Register. */
union {
ioport8_t iir; /**< Interrupt Ident Register (read). */
ioport8_t fcr; /**< FIFO control register (write). */
} __attribute__ ((packed));
ioport8_t lcr; /**< Line Control register. */
ioport8_t mcr; /**< Modem Control Register. */
ioport8_t lsr; /**< Line Status Register. */
} __attribute__ ((packed)) ns16550_t;
 
/** Structure representing the ns16550 device. */
typedef struct {
irq_t irq;
ns16550_t *ns16550;
indev_t *kbrdin;
} ns16550_instance_t;
 
extern ns16550_instance_t *ns16550_init(ns16550_t *, inr_t, cir_t, void *);
extern void ns16550_wire(ns16550_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/drivers/dsrln/dsrlnin.h
0,0 → 1,61
/*
* Copyright (c) 2009 Martin Decky
* 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 genarch
* @{
*/
/**
* @file
* @brief Dummy serial line input.
*/
 
#ifndef KERN_DSRLNIN_H_
#define KERN_DSRLNIN_H_
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
#include <typedefs.h>
 
typedef struct {
ioport8_t data;
} __attribute__ ((packed)) dsrlnin_t;
 
typedef struct {
irq_t irq;
dsrlnin_t *dsrlnin;
indev_t *srlnin;
} dsrlnin_instance_t;
 
extern dsrlnin_instance_t *dsrlnin_init(dsrlnin_t *, inr_t);
extern void dsrlnin_wire(dsrlnin_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/drivers/dsrln/dsrlnout.h
0,0 → 1,48
/*
* Copyright (c) 2009 Martin Decky
* 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 genarch
* @{
*/
/**
* @file
* @brief Dummy serial line output.
*/
 
#ifndef KERN_DSRLNOUT_H_
#define KERN_DSRLNOUT_H_
 
#include <arch/types.h>
#include <typedefs.h>
 
extern void dsrlnout_init(ioport8_t *);
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/drivers/i8042/i8042.h
0,0 → 1,62
/*
* Copyright (c) 2001-2004 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 genarch
* @{
*/
/** @file
*/
 
#ifndef KERN_I8042_H_
#define KERN_I8042_H_
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
#include <typedefs.h>
 
typedef struct {
ioport8_t data;
uint8_t pad[3];
ioport8_t status;
} __attribute__ ((packed)) i8042_t;
 
typedef struct {
irq_t irq;
i8042_t *i8042;
indev_t *kbrdin;
} i8042_instance_t;
 
extern i8042_instance_t *i8042_init(i8042_t *, inr_t);
extern void i8042_wire(i8042_instance_t *, indev_t *);
extern void i8042_cpu_reset(i8042_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/drivers/z8530/z8530.h
0,0 → 1,128
/*
* Copyright (c) 2009 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 genarch
* @{
*/
/**
* @file
* @brief Headers for Zilog 8530 serial controller.
*/
 
#ifndef KERN_Z8530_H_
#define KERN_Z8530_H_
 
#include <ddi/irq.h>
#include <arch/types.h>
#include <console/chardev.h>
 
#define WR0 0
#define WR1 1
#define WR2 2
#define WR3 3
#define WR4 4
#define WR5 5
#define WR6 6
#define WR7 7
#define WR8 8
#define WR9 9
#define WR10 10
#define WR11 11
#define WR12 12
#define WR13 13
#define WR14 14
#define WR15 15
 
#define RR0 0
#define RR1 1
#define RR2 2
#define RR3 3
#define RR8 8
#define RR10 10
#define RR12 12
#define RR13 13
#define RR14 14
#define RR15 15
 
/** Reset pending TX interrupt. */
#define WR0_TX_IP_RST (0x5 << 3)
#define WR0_ERR_RST (0x6 << 3)
 
/** Receive Interrupts Disabled. */
#define WR1_RID (0x0 << 3)
/** Receive Interrupt on First Character or Special Condition. */
#define WR1_RIFCSC (0x1 << 3)
/** Interrupt on All Receive Characters or Special Conditions. */
#define WR1_IARCSC (0x2 << 3)
/** Receive Interrupt on Special Condition. */
#define WR1_RISC (0x3 << 3)
/** Parity Is Special Condition. */
#define WR1_PISC (0x1 << 2)
 
/** Rx Enable. */
#define WR3_RX_ENABLE (0x1 << 0)
/** 8-bits per character. */
#define WR3_RX8BITSCH (0x3 << 6)
 
/** Master Interrupt Enable. */
#define WR9_MIE (0x1 << 3)
 
/** Receive Character Available. */
#define RR0_RCA (0x1 << 0)
 
/** z8530's registers. */
typedef struct {
union {
ioport8_t ctl_b;
ioport8_t status_b;
} __attribute__ ((packed));
uint8_t pad1;
ioport8_t data_b;
uint8_t pad2;
union {
ioport8_t ctl_a;
ioport8_t status_a;
} __attribute__ ((packed));
uint8_t pad3;
ioport8_t data_a;
} __attribute__ ((packed)) z8530_t;
 
/** Structure representing the z8530 device. */
typedef struct {
irq_t irq;
z8530_t *z8530;
indev_t *kbrdin;
} z8530_instance_t;
 
extern z8530_instance_t *z8530_init(z8530_t *, inr_t, cir_t, void *);
extern void z8530_wire(z8530_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/drivers/ega/ega.h
0,0 → 1,56
/*
* Copyright (c) 2001-2004 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 genarch_drivers
* @{
*/
/** @file
*/
 
#ifndef KERN_EGA_H_
#define KERN_EGA_H_
 
#include <arch/types.h>
#include <typedefs.h>
 
#define EGA_COLS 80
#define EGA_ROWS 25
#define EGA_SCREEN (EGA_COLS * EGA_ROWS)
#define EGA_VRAM_SIZE (2 * EGA_SCREEN)
 
/* EGA device registers. */
#define EGA_INDEX_REG 0
#define EGA_DATA_REG 1
 
extern void ega_redraw(void);
extern void ega_init(ioport8_t *, uintptr_t);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/drivers/legacy/ia32/io.h
0,0 → 1,51
/*
* Copyright (c) 2009 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
* @brief This file contains definitions used by architectures with the
* ia32 legacy I/O space (i.e. ia32, amd64 and ia64).
*/
 
#ifndef KERN_LEGACY_IA32_IO_H
#define KERN_LEGACY_IA32_IO_H
 
#include <arch/types.h>
 
#define I8042_BASE ((ioport8_t *) 0x60)
#define EGA_BASE ((ioport8_t *) 0x3d4)
#define NS16550_BASE ((ioport8_t *) 0x3f8)
 
#define EGA_VIDEORAM 0xb8000
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/kbrd/scanc_mac.h
0,0 → 1,48
/*
* Copyright (c) 2009 Jiri Svoboda
* 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 genarch
* @{
*/
/**
* @file
* @brief Scan codes for Macintosh ADB keyboards.
*/
 
#ifndef KERN_SCANC_MAC_H_
#define KERN_SCANC_MAC_H_
 
#define SC_LSHIFT 0x38
#define SC_RSHIFT 0xfd /* Not used */
#define SC_CAPSLOCK 0xfe /* Not used */
#define SC_SCAN_ESCAPE 0xff /* Not used */
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/kbrd/kbrd.h
0,0 → 1,60
/*
* Copyright (c) 2006 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 genarch
* @{
*/
/**
* @file
*/
 
#ifndef KERN_KBD_H_
#define KERN_KBD_H_
 
#include <console/chardev.h>
#include <proc/thread.h>
#include <synch/spinlock.h>
 
typedef struct {
thread_t *thread;
indev_t *sink;
indev_t raw;
SPINLOCK_DECLARE(keylock); /**< keylock protects keyflags and lockflags. */
volatile unsigned int keyflags; /**< Tracking of multiple keypresses. */
volatile unsigned int lockflags; /**< Tracking of multiple keys lockings. */
} kbrd_instance_t;
 
extern kbrd_instance_t *kbrd_init(void);
extern indev_t *kbrd_wire(kbrd_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/kbrd/scanc_pc.h
0,0 → 1,48
/*
* Copyright (c) 2006 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 genarch
* @{
*/
/**
* @file
* @brief Scan codes for PC keyboards.
*/
 
#ifndef KERN_SCANC_PC_H_
#define KERN_SCANC_PC_H_
 
#define SC_LSHIFT 0x2a
#define SC_RSHIFT 0x36
#define SC_CAPSLOCK 0x3a
#define SC_SCAN_ESCAPE 0xe0
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/kbrd/scanc_sun.h
0,0 → 1,48
/*
* Copyright (c) 2006 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 genarch
* @{
*/
/**
* @file
* @brief Scan codes for Sun keyboards.
*/
 
#ifndef KERN_SCANC_SUN_H_
#define KERN_SCANC_SUN_H_
 
#define SC_LSHIFT 0x63
#define SC_RSHIFT 0x6e
#define SC_CAPSLOCK 0x77
#define SC_SCAN_ESCAPE 0xe0
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/kbrd/scanc.h
0,0 → 1,49
/*
* Copyright (c) 2006 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 genarch
* @{
*/
/**
* @file
*/
 
#ifndef KERN_SCANC_H_
#define KERN_SCANC_H_
 
#include <typedefs.h>
 
#define SCANCODES 128
 
extern wchar_t sc_primary_map[SCANCODES];
extern wchar_t sc_secondary_map[SCANCODES];
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/kbrd
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/srln/srln.h
0,0 → 1,55
/*
* Copyright (c) 2009 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 genarch
* @{
*/
/**
* @file
*/
 
#ifndef KERN_SRLN_H_
#define KERN_SRLN_H_
 
#include <console/chardev.h>
#include <proc/thread.h>
 
typedef struct {
thread_t *thread;
indev_t *sink;
indev_t raw;
} srln_instance_t;
 
extern srln_instance_t *srln_init(void);
extern indev_t *srln_wire(srln_instance_t *, indev_t *);
 
#endif
 
/** @}
*/
/branches/arm/kernel/genarch/include/fb/font-8x16.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
/** @addtogroup genarch
* @{
*/
/** @file
35,11 → 35,15
#ifndef KERN_FONT_8X16_H_
#define KERN_FONT_8X16_H_
 
#define FONT_GLIPHS 256
#define FONT_SCANLINES 16
#define FONT_GLYPHS 2899
#define FONT_WIDTH 8
#define FONT_SCANLINES 16
 
extern unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES];
#include <typedefs.h>
 
extern uint16_t fb_font_glyph(const wchar_t ch);
extern uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES];
 
#endif
 
/** @}
/branches/arm/kernel/genarch/include/fb/visuals.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
/** @addtogroup genarch
* @{
*/
/** @file
35,16 → 35,16
#ifndef KERN_VISUALS_H_
#define KERN_VISUALS_H_
 
#define VISUAL_INDIRECT_8 0
#define VISUAL_INDIRECT_8 0
 
#define VISUAL_RGB_5_5_5 1
#define VISUAL_RGB_5_6_5 2
#define VISUAL_RGB_8_8_8 3
#define VISUAL_RGB_8_8_8_0 4
#define VISUAL_RGB_0_8_8_8 5
#define VISUAL_RGB_5_5_5 1
#define VISUAL_RGB_5_6_5 2
#define VISUAL_RGB_8_8_8 3
#define VISUAL_RGB_8_8_8_0 4
#define VISUAL_RGB_0_8_8_8 5
 
#define VISUAL_BGR_0_8_8_8 6
#define VISUAL_BGR_8_8_8_0 7
#define VISUAL_BGR_0_8_8_8 6
#define VISUAL_BGR_8_8_8 7
 
#endif
 
/branches/arm/kernel/genarch/include/fb/fb.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
/** @addtogroup genarch
* @{
*/
/** @file
38,9 → 38,37
#include <arch/types.h>
#include <synch/spinlock.h>
 
/**
* Properties of the framebuffer device.
*/
typedef struct fb_properties {
/** Physical address of the framebuffer device. */
uintptr_t addr;
 
/**
* Address where the first (top left) pixel is mapped,
* relative to "addr".
*/
unsigned int offset;
 
/** Screen width in pixels. */
unsigned int x;
 
/** Screen height in pixels. */
unsigned int y;
 
/** Bytes per one scanline. */
unsigned int scan;
 
/** Color model. */
unsigned int visual;
} fb_properties_t;
 
SPINLOCK_EXTERN(fb_lock);
void fb_init(uintptr_t addr, unsigned int x, unsigned int y, unsigned int scan, unsigned int visual);
 
void fb_redraw(void);
void fb_init(fb_properties_t *props);
 
#endif
 
/** @}
/branches/arm/kernel/genarch/include/fb/logo-196x66.h
0,0 → 1,49
/*
* Copyright (c) 2008 Martin Decky
* 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 genarch
* @{
*/
/** @file
*/
 
#ifndef KERN_LOGO_196X66_H_
#define KERN_LOGO_196X66_H_
 
#define LOGO_WIDTH 196
#define LOGO_HEIGHT 66
#define LOGO_COLOR 0xffffff
 
#include <arch/types.h>
 
extern uint32_t fb_logo[LOGO_WIDTH * LOGO_HEIGHT];
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/multiboot/multiboot.h
0,0 → 1,100
/*
* Copyright (c) 2009 Jiri Svoboda
* 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 genarch
* @{
*/
/** @file
*/
 
#ifndef KERN_MULTIBOOT_H_
#define KERN_MULTIBOOT_H_
 
#include <arch/types.h>
#include <arch/boot/memmap.h>
 
/** Multiboot 32-bit address. */
typedef uint32_t mbaddr_t;
 
/** Multiboot mod structure */
typedef struct {
mbaddr_t start;
mbaddr_t end;
mbaddr_t string;
uint32_t reserved;
} __attribute__ ((packed)) multiboot_mod_t;
 
/** Multiboot mmap structure */
typedef struct {
uint32_t size;
e820memmap_t mm_info;
} __attribute__ ((packed)) multiboot_mmap_t;
 
/** Multiboot information structure */
typedef struct {
uint32_t flags;
uint32_t mem_lower;
uint32_t mem_upper;
uint32_t boot_device;
uint32_t cmdline;
uint32_t mods_count;
mbaddr_t mods_addr;
uint32_t syms[4];
uint32_t mmap_length;
mbaddr_t mmap_addr;
/* ... */
} __attribute__ ((packed)) multiboot_info_t;
 
enum multiboot_info_flags {
MBINFO_FLAGS_MEM = 0x01,
MBINFO_FLAGS_BOOT = 0x02,
MBINFO_FLAGS_CMDLINE = 0x04,
MBINFO_FLAGS_MODS = 0x08,
MBINFO_FLAGS_SYMS1 = 0x10,
MBINFO_FLAGS_SYMS2 = 0x20,
MBINFO_FLAGS_MMAP = 0x40
/* ... */
};
 
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002
 
/** Convert 32-bit multiboot address to a pointer. */
#define MULTIBOOT_PTR(mba) ((void *)(uintptr_t) (mba))
 
extern void multiboot_info_parse(uint32_t, const multiboot_info_t *);
 
#endif
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/include/ofw/ofw_tree.h
30,6 → 30,7
#define KERN_OFW_TREE_H_
 
#include <arch/types.h>
#include <ddi/irq.h>
#include <typedefs.h>
 
#define OFW_TREE_PROPERTY_MAX_NAMELEN 32
43,11 → 44,11
ofw_tree_node_t *peer;
ofw_tree_node_t *child;
 
uint32_t node_handle; /**< Old OpenFirmware node handle. */
uint32_t node_handle; /**< Old OpenFirmware node handle. */
 
char *da_name; /**< Disambigued name. */
char *da_name; /**< Disambigued name. */
 
unsigned properties; /**< Number of properties. */
unsigned properties; /**< Number of properties. */
ofw_tree_property_t *property;
/**
105,7 → 106,7
uint32_t child_space;
uint32_t child_base;
uint32_t parent_space;
uint64_t parent_base; /* group phys.mid and phys.lo together */
uint64_t parent_base; /* group phys.mid and phys.lo together */
uint32_t size;
} __attribute__ ((packed));
typedef struct ofw_ebus_range ofw_ebus_range_t;
127,8 → 128,8
typedef struct ofw_ebus_intr_mask ofw_ebus_intr_mask_t;
 
struct ofw_pci_reg {
uint32_t space; /* needs to be masked to obtain pure space id */
uint64_t addr; /* group phys.mid and phys.lo together */
uint32_t space; /* needs to be masked to obtain pure space id */
uint64_t addr; /* group phys.mid and phys.lo together */
uint64_t size;
} __attribute__ ((packed));
typedef struct ofw_pci_reg ofw_pci_reg_t;
135,7 → 136,7
 
struct ofw_pci_range {
uint32_t space;
uint64_t child_base; /* group phys.mid and phys.lo together */
uint64_t child_base; /* group phys.mid and phys.lo together */
uint64_t parent_base;
uint64_t size;
} __attribute__ ((packed));
160,27 → 161,43
} __attribute__ ((packed));
typedef struct ofw_upa_reg ofw_upa_reg_t;
 
extern void ofw_tree_init(ofw_tree_node_t *root);
extern void ofw_tree_init(ofw_tree_node_t *);
extern void ofw_tree_print(void);
extern const char *ofw_tree_node_name(const ofw_tree_node_t *node);
extern ofw_tree_node_t *ofw_tree_lookup(const char *path);
extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name);
extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name);
extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *device_type);
extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *device_type);
extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle);
extern const char *ofw_tree_node_name(const ofw_tree_node_t *);
extern ofw_tree_node_t *ofw_tree_lookup(const char *);
extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *,
const char *);
extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *, const char *);
extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *,
const char *);
extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *,
const char *);
extern ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node,
const char *name);
extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *,
uint32_t);
 
extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uintptr_t *pa);
extern bool ofw_central_apply_ranges(ofw_tree_node_t *node, ofw_central_reg_t *reg, uintptr_t *pa);
extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa);
extern bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa);
extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *node, ofw_sbus_reg_t *reg, uintptr_t *pa);
extern bool ofw_upa_apply_ranges(ofw_tree_node_t *node, ofw_upa_reg_t *reg, uintptr_t *pa);
extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *, ofw_fhc_reg_t *,
uintptr_t *);
extern bool ofw_central_apply_ranges(ofw_tree_node_t *, ofw_central_reg_t *,
uintptr_t *);
extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *, ofw_ebus_reg_t *,
uintptr_t *);
extern bool ofw_pci_apply_ranges(ofw_tree_node_t *, ofw_pci_reg_t *,
uintptr_t *);
extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *, ofw_sbus_reg_t *,
uintptr_t *);
extern bool ofw_upa_apply_ranges(ofw_tree_node_t *, ofw_upa_reg_t *,
uintptr_t *);
 
extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, ofw_pci_reg_t *out);
extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *, ofw_pci_reg_t *,
ofw_pci_reg_t *);
 
extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *inr);
extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr);
extern bool ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, int *inr);
extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *, ofw_fhc_reg_t *,
uint32_t, int *, cir_t *, void **);
extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *, ofw_ebus_reg_t *,
uint32_t, int *, cir_t *, void **);
extern bool ofw_pci_map_interrupt(ofw_tree_node_t *, ofw_pci_reg_t *,
int, int *, cir_t *, void **);
 
#endif
/branches/arm/kernel/genarch/src/kbd/ns16550.c
File deleted
/branches/arm/kernel/genarch/src/kbd/i8042.c
File deleted
/branches/arm/kernel/genarch/src/kbd/scanc_pl050.c
File deleted
/branches/arm/kernel/genarch/src/kbd/key.c
File deleted
/branches/arm/kernel/genarch/src/kbd/z8530.c
File deleted
/branches/arm/kernel/genarch/src/kbd/scanc_pc.c
File deleted
/branches/arm/kernel/genarch/src/kbd/scanc_sun.c
File deleted
/branches/arm/kernel/genarch/src/drivers/via-cuda/cuda.c
0,0 → 1,360
/*
* Copyright (c) 2006 Martin Decky
* Copyright (c) 2009 Jiri Svoboda
* 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 genarch
* @{
*/
/** @file
*/
 
#include <genarch/drivers/via-cuda/cuda.h>
#include <console/chardev.h>
#include <ddi/irq.h>
#include <arch/asm.h>
#include <mm/slab.h>
#include <ddi/device.h>
#include <synch/spinlock.h>
 
static irq_ownership_t cuda_claim(irq_t *irq);
static void cuda_irq_handler(irq_t *irq);
 
static void cuda_irq_listen(irq_t *irq);
static void cuda_irq_receive(irq_t *irq);
static void cuda_irq_rcv_end(irq_t *irq, void *buf, size_t *len);
static void cuda_irq_send_start(irq_t *irq);
static void cuda_irq_send(irq_t *irq);
 
static void cuda_packet_handle(cuda_instance_t *instance, uint8_t *buf, size_t len);
static void cuda_send_start(cuda_instance_t *instance);
static void cuda_autopoll_set(cuda_instance_t *instance, bool enable);
 
/** B register fields */
enum {
TREQ = 0x08,
TACK = 0x10,
TIP = 0x20
};
 
/** IER register fields */
enum {
IER_CLR = 0x00,
IER_SET = 0x80,
 
SR_INT = 0x04,
ALL_INT = 0x7f
};
 
/** ACR register fields */
enum {
SR_OUT = 0x10
};
 
/** Packet types */
enum {
PT_ADB = 0x00,
PT_CUDA = 0x01
};
 
/** CUDA packet types */
enum {
CPT_AUTOPOLL = 0x01
};
 
cuda_instance_t *cuda_init(cuda_t *dev, inr_t inr, cir_t cir, void *cir_arg)
{
cuda_instance_t *instance
= malloc(sizeof(cuda_instance_t), FRAME_ATOMIC);
if (instance) {
instance->cuda = dev;
instance->kbrdin = NULL;
instance->xstate = cx_listen;
instance->bidx = 0;
instance->snd_bytes = 0;
 
spinlock_initialize(&instance->dev_lock, "cuda_dev");
 
/* Disable all interrupts from CUDA. */
pio_write_8(&dev->ier, IER_CLR | ALL_INT);
 
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = cuda_claim;
instance->irq.handler = cuda_irq_handler;
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
instance->irq.preack = true;
}
return instance;
}
 
#include <print.h>
void cuda_wire(cuda_instance_t *instance, indev_t *kbrdin)
{
cuda_t *dev = instance->cuda;
 
ASSERT(instance);
ASSERT(kbrdin);
 
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
 
/* Enable SR interrupt. */
pio_write_8(&dev->ier, TIP | TREQ);
pio_write_8(&dev->ier, IER_SET | SR_INT);
 
/* Enable ADB autopolling. */
cuda_autopoll_set(instance, true);
}
 
static irq_ownership_t cuda_claim(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t ifr;
 
spinlock_lock(&instance->dev_lock);
ifr = pio_read_8(&dev->ifr);
spinlock_unlock(&instance->dev_lock);
 
if ((ifr & SR_INT) == 0)
return IRQ_DECLINE;
 
return IRQ_ACCEPT;
}
 
static void cuda_irq_handler(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
uint8_t rbuf[CUDA_RCV_BUF_SIZE];
size_t len;
bool handle;
 
handle = false;
len = 0;
 
spinlock_lock(&instance->dev_lock);
 
/* Lower IFR.SR_INT so that CUDA can generate next int by raising it. */
pio_write_8(&instance->cuda->ifr, SR_INT);
 
switch (instance->xstate) {
case cx_listen: cuda_irq_listen(irq); break;
case cx_receive: cuda_irq_receive(irq); break;
case cx_rcv_end: cuda_irq_rcv_end(irq, rbuf, &len);
handle = true; break;
case cx_send_start: cuda_irq_send_start(irq); break;
case cx_send: cuda_irq_send(irq); break;
}
 
spinlock_unlock(&instance->dev_lock);
 
/* Handle an incoming packet. */
if (handle)
cuda_packet_handle(instance, rbuf, len);
}
 
/** Interrupt in listen state.
*
* Start packet reception.
*/
static void cuda_irq_listen(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) != 0) {
printf("cuda_irq_listen: no TREQ?!\n");
return;
}
 
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP);
instance->xstate = cx_receive;
}
 
/** Interrupt in receive state.
*
* Receive next byte of packet.
*/
static void cuda_irq_receive(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b, data;
 
data = pio_read_8(&dev->sr);
if (instance->bidx < CUDA_RCV_BUF_SIZE)
instance->rcv_buf[instance->bidx++] = data;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) == 0) {
pio_write_8(&dev->b, b ^ TACK);
} else {
pio_write_8(&dev->b, b | TACK | TIP);
instance->xstate = cx_rcv_end;
}
}
 
/** Interrupt in rcv_end state.
*
* Terminate packet reception. Either go back to listen state or start
* receiving another packet if CUDA has one for us.
*/
static void cuda_irq_rcv_end(irq_t *irq, void *buf, size_t *len)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t data, b;
 
b = pio_read_8(&dev->b);
data = pio_read_8(&dev->sr);
 
if ((b & TREQ) == 0) {
instance->xstate = cx_receive;
pio_write_8(&dev->b, b & ~TIP);
} else {
instance->xstate = cx_listen;
cuda_send_start(instance);
}
 
memcpy(buf, instance->rcv_buf, instance->bidx);
*len = instance->bidx;
instance->bidx = 0;
}
 
/** Interrupt in send_start state.
*
* Process result of sending first byte (and send second on success).
*/
static void cuda_irq_send_start(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
uint8_t b;
 
b = pio_read_8(&dev->b);
 
if ((b & TREQ) == 0) {
/* Collision */
pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) | TIP | TACK);
instance->xstate = cx_listen;
return;
}
 
pio_write_8(&dev->sr, instance->snd_buf[1]);
pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
instance->bidx = 2;
 
instance->xstate = cx_send;
}
 
/** Interrupt in send state.
*
* Send next byte or terminate transmission.
*/
static void cuda_irq_send(irq_t *irq)
{
cuda_instance_t *instance = irq->instance;
cuda_t *dev = instance->cuda;
 
if (instance->bidx < instance->snd_bytes) {
/* Send next byte. */
pio_write_8(&dev->sr, instance->snd_buf[instance->bidx++]);
pio_write_8(&dev->b, pio_read_8(&dev->b) ^ TACK);
return;
}
 
/* End transfer. */
instance->snd_bytes = 0;
instance->bidx = 0;
 
pio_write_8(&dev->acr, pio_read_8(&dev->acr) & ~SR_OUT);
pio_read_8(&dev->sr);
pio_write_8(&dev->b, pio_read_8(&dev->b) | TACK | TIP);
 
instance->xstate = cx_listen;
/* TODO: Match reply with request. */
}
 
static void cuda_packet_handle(cuda_instance_t *instance, uint8_t *data, size_t len)
{
if (data[0] != 0x00 || data[1] != 0x40 || (data[2] != 0x2c
&& data[2] != 0x8c))
return;
 
/* The packet contains one or two scancodes. */
if (data[3] != 0xff)
indev_push_character(instance->kbrdin, data[3]);
if (data[4] != 0xff)
indev_push_character(instance->kbrdin, data[4]);
}
 
static void cuda_autopoll_set(cuda_instance_t *instance, bool enable)
{
instance->snd_buf[0] = PT_CUDA;
instance->snd_buf[1] = CPT_AUTOPOLL;
instance->snd_buf[2] = enable ? 0x01 : 0x00;
instance->snd_bytes = 3;
instance->bidx = 0;
 
cuda_send_start(instance);
}
 
static void cuda_send_start(cuda_instance_t *instance)
{
cuda_t *dev = instance->cuda;
 
ASSERT(instance->xstate == cx_listen);
 
if (instance->snd_bytes == 0)
return;
 
/* Check for incoming data. */
if ((pio_read_8(&dev->b) & TREQ) == 0)
return;
 
pio_write_8(&dev->acr, pio_read_8(&dev->acr) | SR_OUT);
pio_write_8(&dev->sr, instance->snd_buf[0]);
pio_write_8(&dev->b, pio_read_8(&dev->b) & ~TIP);
 
instance->xstate = cx_send_start;
}
 
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/drivers/ega/ega.c
0,0 → 1,587
/*
* Copyright (c) 2001-2004 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 genarch_drivers
* @{
*/
/**
* @file
* @brief EGA driver.
*/
 
#include <genarch/drivers/ega/ega.h>
#include <putchar.h>
#include <mm/page.h>
#include <mm/as.h>
#include <mm/slab.h>
#include <arch/mm/page.h>
#include <synch/spinlock.h>
#include <arch/types.h>
#include <arch/asm.h>
#include <memstr.h>
#include <string.h>
#include <console/chardev.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <ddi/ddi.h>
 
/*
* The EGA driver.
* Simple and short. Function for displaying characters and "scrolling".
*/
 
SPINLOCK_INITIALIZE(egalock);
static uint32_t ega_cursor;
static uint8_t *videoram;
static uint8_t *backbuf;
static ioport8_t *ega_base;
 
#define SPACE 0x20
#define STYLE 0x1e
#define INVAL 0x17
 
#define EMPTY_CHAR ((STYLE << 8) | SPACE)
 
static uint16_t ega_oem_glyph(const wchar_t ch)
{
if ((ch >= 0x0000) && (ch <= 0x007f))
return ch;
if (ch == 0x00a0)
return 255;
if (ch == 0x00a1)
return 173;
if ((ch >= 0x00a2) && (ch <= 0x00a3))
return (ch - 7);
if (ch == 0x00a5)
return 157;
if (ch == 0x00aa)
return 166;
if (ch == 0x00ab)
return 174;
if (ch == 0x00ac)
return 170;
if (ch == 0x00b0)
return 248;
if (ch == 0x00b1)
return 241;
if (ch == 0x00b2)
return 253;
if (ch == 0x00b5)
return 230;
if (ch == 0x00b7)
return 250;
if (ch == 0x00ba)
return 167;
if (ch == 0x00bb)
return 175;
if (ch == 0x00bc)
return 172;
if (ch == 0x00bd)
return 171;
if (ch == 0x00bf)
return 168;
if ((ch >= 0x00c4) && (ch <= 0x00c5))
return (ch - 54);
if (ch == 0x00c6)
return 146;
if (ch == 0x00c7)
return 128;
if (ch == 0x00c9)
return 144;
if (ch == 0x00d1)
return 165;
if (ch == 0x00d6)
return 153;
if (ch == 0x00dc)
return 154;
if (ch == 0x00df)
return 225;
if (ch == 0x00e0)
return 133;
if (ch == 0x00e1)
return 160;
if (ch == 0x00e2)
return 131;
if (ch == 0x00e4)
return 132;
if (ch == 0x00e5)
return 134;
if (ch == 0x00e6)
return 145;
if (ch == 0x00e7)
return 135;
if (ch == 0x00e8)
return 138;
if (ch == 0x00e9)
return 130;
if ((ch >= 0x00ea) && (ch <= 0x00eb))
return (ch - 98);
if (ch == 0x00ec)
return 141;
if (ch == 0x00ed)
return 161;
if (ch == 0x00ee)
return 140;
if (ch == 0x00ef)
return 139;
if (ch == 0x00f1)
return 164;
if (ch == 0x00f2)
return 149;
if (ch == 0x00f3)
return 162;
if (ch == 0x00f4)
return 147;
if (ch == 0x00f6)
return 148;
if (ch == 0x00f7)
return 246;
if (ch == 0x00f9)
return 151;
if (ch == 0x00fa)
return 163;
if (ch == 0x00fb)
return 150;
if (ch == 0x00fc)
return 129;
if (ch == 0x00ff)
return 152;
if (ch == 0x0192)
return 159;
if (ch == 0x0393)
return 226;
if (ch == 0x0398)
return 233;
if (ch == 0x03a3)
return 228;
if (ch == 0x03a6)
return 232;
if (ch == 0x03a9)
return 234;
if (ch == 0x03b1)
return 224;
if (ch == 0x03b4)
return 235;
if (ch == 0x03b5)
return 238;
if (ch == 0x03c0)
return 227;
if (ch == 0x03c3)
return 229;
if (ch == 0x03c4)
return 231;
if (ch == 0x03c6)
return 237;
if (ch == 0x207f)
return 252;
if (ch == 0x20a7)
return 158;
if (ch == 0x2219)
return 249;
if (ch == 0x221a)
return 251;
if (ch == 0x221e)
return 236;
if (ch == 0x2229)
return 239;
if (ch == 0x2248)
return 247;
if (ch == 0x2261)
return 240;
if (ch == 0x2264)
return 243;
if (ch == 0x2265)
return 242;
if (ch == 0x2310)
return 169;
if ((ch >= 0x2320) && (ch <= 0x2321))
return (ch - 8748);
if (ch == 0x2500)
return 196;
if (ch == 0x2502)
return 179;
if (ch == 0x250c)
return 218;
if (ch == 0x2510)
return 191;
if (ch == 0x2514)
return 192;
if (ch == 0x2518)
return 217;
if (ch == 0x251c)
return 195;
if (ch == 0x2524)
return 180;
if (ch == 0x252c)
return 194;
if (ch == 0x2534)
return 193;
if (ch == 0x253c)
return 197;
if (ch == 0x2550)
return 205;
if (ch == 0x2551)
return 186;
if ((ch >= 0x2552) && (ch <= 0x2553))
return (ch - 9341);
if (ch == 0x2554)
return 201;
if (ch == 0x2555)
return 184;
if (ch == 0x2556)
return 183;
if (ch == 0x2557)
return 187;
if (ch == 0x2558)
return 212;
if (ch == 0x2559)
return 211;
if (ch == 0x255a)
return 200;
if (ch == 0x255b)
return 190;
if (ch == 0x255c)
return 189;
if (ch == 0x255d)
return 188;
if ((ch >= 0x255e) && (ch <= 0x255f))
return (ch - 9368);
if (ch == 0x2560)
return 204;
if ((ch >= 0x2561) && (ch <= 0x2562))
return (ch - 9388);
if (ch == 0x2563)
return 185;
if ((ch >= 0x2564) && (ch <= 0x2565))
return (ch - 9363);
if (ch == 0x2566)
return 203;
if ((ch >= 0x2567) && (ch <= 0x2568))
return (ch - 9368);
if (ch == 0x2569)
return 202;
if (ch == 0x256a)
return 216;
if (ch == 0x256b)
return 215;
if (ch == 0x256c)
return 206;
if (ch == 0x2580)
return 223;
if (ch == 0x2584)
return 220;
if (ch == 0x2588)
return 219;
if (ch == 0x258c)
return 221;
if (ch == 0x2590)
return 222;
if ((ch >= 0x2591) && (ch <= 0x2593))
return (ch - 9441);
return 256;
}
 
/*
* This function takes care of scrolling.
*/
static void ega_check_cursor(bool silent)
{
if (ega_cursor < EGA_SCREEN)
return;
memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2),
(EGA_SCREEN - EGA_COLS) * 2);
memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
if (!silent) {
memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2),
(EGA_SCREEN - EGA_COLS) * 2);
memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR);
}
ega_cursor = ega_cursor - EGA_COLS;
}
 
static void ega_show_cursor(bool silent)
{
if (!silent) {
pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
uint8_t stat = pio_read_8(ega_base + EGA_DATA_REG);
pio_write_8(ega_base + EGA_INDEX_REG, 0x0a);
pio_write_8(ega_base + EGA_DATA_REG, stat & (~(1 << 5)));
}
}
 
static void ega_move_cursor(bool silent)
{
if (!silent) {
pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff));
pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff));
}
}
 
static void ega_sync_cursor(bool silent)
{
if (!silent) {
pio_write_8(ega_base + EGA_INDEX_REG, 0x0e);
uint8_t hi = pio_read_8(ega_base + EGA_DATA_REG);
pio_write_8(ega_base + EGA_INDEX_REG, 0x0f);
uint8_t lo = pio_read_8(ega_base + EGA_DATA_REG);
ega_cursor = (hi << 8) | lo;
} else
ega_cursor = 0;
if (ega_cursor >= EGA_SCREEN)
ega_cursor = 0;
if ((ega_cursor % EGA_COLS) != 0)
ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
memsetw(backbuf + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
if (!silent)
memsetw(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR);
ega_check_cursor(silent);
ega_move_cursor(silent);
ega_show_cursor(silent);
}
 
static void ega_display_char(wchar_t ch, bool silent)
{
uint16_t index = ega_oem_glyph(ch);
uint8_t glyph;
uint8_t style;
if ((index >> 8)) {
glyph = U_SPECIAL;
style = INVAL;
} else {
glyph = index & 0xff;
style = STYLE;
}
backbuf[ega_cursor * 2] = glyph;
backbuf[ega_cursor * 2 + 1] = style;
if (!silent) {
videoram[ega_cursor * 2] = glyph;
videoram[ega_cursor * 2 + 1] = style;
}
}
 
static void ega_putchar(outdev_t *dev __attribute__((unused)), wchar_t ch, bool silent)
{
ipl_t ipl;
ipl = interrupts_disable();
spinlock_lock(&egalock);
switch (ch) {
case '\n':
ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS;
break;
case '\t':
ega_cursor = (ega_cursor + 8) - ega_cursor % 8;
break;
case '\b':
if (ega_cursor % EGA_COLS)
ega_cursor--;
break;
default:
ega_display_char(ch, silent);
ega_cursor++;
break;
}
ega_check_cursor(silent);
ega_move_cursor(silent);
spinlock_unlock(&egalock);
interrupts_restore(ipl);
}
 
static outdev_t ega_console;
static outdev_operations_t ega_ops = {
.write = ega_putchar
};
 
void ega_init(ioport8_t *base, uintptr_t videoram_phys)
{
/* Initialize the software structure. */
ega_base = base;
backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0);
if (!backbuf)
panic("Unable to allocate backbuffer.");
videoram = (uint8_t *) hw_map(videoram_phys, EGA_VRAM_SIZE);
/* Synchronize the back buffer and cursor position. */
memcpy(backbuf, videoram, EGA_VRAM_SIZE);
ega_sync_cursor(silent);
outdev_initialize("ega", &ega_console, &ega_ops);
stdout = &ega_console;
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 2);
sysinfo_set_item_val("fb.width", NULL, EGA_COLS);
sysinfo_set_item_val("fb.height", NULL, EGA_ROWS);
sysinfo_set_item_val("fb.blinking", NULL, true);
sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys);
}
 
void ega_redraw(void)
{
memcpy(videoram, backbuf, EGA_VRAM_SIZE);
ega_move_cursor(silent);
ega_show_cursor(silent);
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/drivers/ns16550/ns16550.c
0,0 → 1,123
/*
* Copyright (c) 2009 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 genarch
* @{
*/
/**
* @file
* @brief NS 16550 serial controller driver.
*/
 
#include <genarch/drivers/ns16550/ns16550.h>
#include <ddi/irq.h>
#include <arch/asm.h>
#include <console/chardev.h>
#include <mm/slab.h>
#include <ddi/device.h>
 
#define LSR_DATA_READY 0x01
 
static irq_ownership_t ns16550_claim(irq_t *irq)
{
ns16550_instance_t *instance = irq->instance;
ns16550_t *dev = instance->ns16550;
if (pio_read_8(&dev->lsr) & LSR_DATA_READY)
return IRQ_ACCEPT;
else
return IRQ_DECLINE;
}
 
static void ns16550_irq_handler(irq_t *irq)
{
ns16550_instance_t *instance = irq->instance;
ns16550_t *dev = instance->ns16550;
if (pio_read_8(&dev->lsr) & LSR_DATA_READY) {
uint8_t data = pio_read_8(&dev->rbr);
indev_push_character(instance->kbrdin, data);
}
}
 
/**< Clear input buffer. */
static void ns16550_clear_buffer(ns16550_t *dev)
{
while ((pio_read_8(&dev->lsr) & LSR_DATA_READY))
(void) pio_read_8(&dev->rbr);
}
 
/** Initialize ns16550.
*
* @param dev Addrress of the beginning of the device in I/O space.
* @param devno Device number.
* @param inr Interrupt number.
* @param cir Clear interrupt function.
* @param cir_arg First argument to cir.
*
* @return Keyboard instance or NULL on failure.
*
*/
ns16550_instance_t *ns16550_init(ns16550_t *dev, inr_t inr, cir_t cir, void *cir_arg)
{
ns16550_instance_t *instance
= malloc(sizeof(ns16550_instance_t), FRAME_ATOMIC);
if (instance) {
instance->ns16550 = dev;
instance->kbrdin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = ns16550_claim;
instance->irq.handler = ns16550_irq_handler;
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
}
return instance;
}
 
void ns16550_wire(ns16550_instance_t *instance, indev_t *kbrdin)
{
ASSERT(instance);
ASSERT(kbrdin);
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
ns16550_clear_buffer(instance->ns16550);
/* Enable interrupts */
pio_write_8(&instance->ns16550->ier, IER_ERBFI);
pio_write_8(&instance->ns16550->mcr, MCR_OUT2);
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/drivers/dsrln/dsrlnin.c
0,0 → 1,85
/*
* Copyright (c) 2009 Martin Decky
* 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 genarch
* @{
*/
/**
* @file
* @brief Dummy serial line input.
*/
 
#include <genarch/drivers/dsrln/dsrlnin.h>
#include <console/chardev.h>
#include <mm/slab.h>
#include <arch/asm.h>
#include <ddi/device.h>
 
static irq_ownership_t dsrlnin_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
static void dsrlnin_irq_handler(irq_t *irq)
{
dsrlnin_instance_t *instance = irq->instance;
dsrlnin_t *dev = instance->dsrlnin;
indev_push_character(instance->srlnin, pio_read_8(&dev->data));
}
 
dsrlnin_instance_t *dsrlnin_init(dsrlnin_t *dev, inr_t inr)
{
dsrlnin_instance_t *instance
= malloc(sizeof(dsrlnin_instance_t), FRAME_ATOMIC);
if (instance) {
instance->dsrlnin = dev;
instance->srlnin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = dsrlnin_claim;
instance->irq.handler = dsrlnin_irq_handler;
instance->irq.instance = instance;
}
return instance;
}
 
void dsrlnin_wire(dsrlnin_instance_t *instance, indev_t *srlnin)
{
ASSERT(instance);
ASSERT(srlnin);
instance->srlnin = srlnin;
irq_register(&instance->irq);
}
 
/** @}
*/
/branches/arm/kernel/genarch/src/drivers/dsrln/dsrlnout.c
0,0 → 1,76
/*
* Copyright (c) 2009 Martin Decky
* 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 genarch
* @{
*/
/**
* @file
* @brief Dummy serial line output.
*/
 
 
#include <genarch/drivers/dsrln/dsrlnout.h>
#include <console/chardev.h>
#include <arch/asm.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <string.h>
 
static ioport8_t *dsrlnout_base;
 
static void dsrlnout_putchar(outdev_t *dev __attribute__((unused)), const wchar_t ch, bool silent)
{
if (!silent) {
if (ascii_check(ch))
pio_write_8(dsrlnout_base, ch);
else
pio_write_8(dsrlnout_base, U_SPECIAL);
}
}
 
static outdev_t dsrlnout_console;
static outdev_operations_t dsrlnout_ops = {
.write = dsrlnout_putchar
};
 
void dsrlnout_init(ioport8_t *base)
{
/* Initialize the software structure. */
dsrlnout_base = base;
outdev_initialize("dsrlnout", &dsrlnout_console, &dsrlnout_ops);
stdout = &dsrlnout_console;
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 3);
sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(base));
}
 
/** @}
*/
/branches/arm/kernel/genarch/src/drivers/i8042/i8042.c
0,0 → 1,127
/*
* Copyright (c) 2009 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 genarch
* @{
*/
/**
* @file
* @brief i8042 processor driver
*
* It takes care of the i8042 serial communication.
*
*/
 
#include <genarch/drivers/i8042/i8042.h>
#include <genarch/drivers/legacy/ia32/io.h>
#include <arch/asm.h>
#include <console/chardev.h>
#include <mm/slab.h>
#include <ddi/device.h>
 
#define i8042_SET_COMMAND 0x60
#define i8042_COMMAND 0x69
#define i8042_CPU_RESET 0xfe
 
#define i8042_BUFFER_FULL_MASK 0x01
#define i8042_WAIT_MASK 0x02
 
static irq_ownership_t i8042_claim(irq_t *irq)
{
i8042_instance_t *i8042_instance = irq->instance;
i8042_t *dev = i8042_instance->i8042;
if (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK)
return IRQ_ACCEPT;
else
return IRQ_DECLINE;
}
 
static void i8042_irq_handler(irq_t *irq)
{
i8042_instance_t *instance = irq->instance;
i8042_t *dev = instance->i8042;
uint8_t status;
if (((status = pio_read_8(&dev->status)) & i8042_BUFFER_FULL_MASK)) {
uint8_t data = pio_read_8(&dev->data);
indev_push_character(instance->kbrdin, data);
}
}
 
/**< Clear input buffer. */
static void i8042_clear_buffer(i8042_t *dev)
{
while (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK)
(void) pio_read_8(&dev->data);
}
 
/** Initialize i8042. */
i8042_instance_t *i8042_init(i8042_t *dev, inr_t inr)
{
i8042_instance_t *instance
= malloc(sizeof(i8042_instance_t), FRAME_ATOMIC);
if (instance) {
instance->i8042 = dev;
instance->kbrdin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = i8042_claim;
instance->irq.handler = i8042_irq_handler;
instance->irq.instance = instance;
}
return instance;
}
 
void i8042_wire(i8042_instance_t *instance, indev_t *kbrdin)
{
ASSERT(instance);
ASSERT(kbrdin);
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
i8042_clear_buffer(instance->i8042);
}
 
/* Reset CPU by pulsing pin 0 */
void i8042_cpu_reset(i8042_t *dev)
{
interrupts_disable();
i8042_clear_buffer(dev);
/* Reset CPU */
pio_write_8(&dev->status, i8042_CPU_RESET);
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/drivers/z8530/z8530.c
0,0 → 1,136
/*
* Copyright (c) 2009 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 genarch
* @{
*/
/**
* @file
* @brief Zilog 8530 serial controller driver.
*/
 
#include <genarch/drivers/z8530/z8530.h>
#include <console/chardev.h>
#include <ddi/irq.h>
#include <arch/asm.h>
#include <mm/slab.h>
#include <ddi/device.h>
 
static inline void z8530_write(ioport8_t *ctl, uint8_t reg, uint8_t val)
{
/*
* Registers 8-15 will automatically issue the Point High
* command as their bit 3 is 1.
*/
pio_write_8(ctl, reg); /* Select register */
pio_write_8(ctl, val); /* Write value */
}
 
static inline uint8_t z8530_read(ioport8_t *ctl, uint8_t reg)
{
/*
* Registers 8-15 will automatically issue the Point High
* command as their bit 3 is 1.
*/
pio_write_8(ctl, reg); /* Select register */
return pio_read_8(ctl);
}
 
static irq_ownership_t z8530_claim(irq_t *irq)
{
z8530_instance_t *instance = irq->instance;
z8530_t *dev = instance->z8530;
if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA)
return IRQ_ACCEPT;
else
return IRQ_DECLINE;
}
 
static void z8530_irq_handler(irq_t *irq)
{
z8530_instance_t *instance = irq->instance;
z8530_t *dev = instance->z8530;
if (z8530_read(&dev->ctl_a, RR0) & RR0_RCA) {
uint8_t data = z8530_read(&dev->ctl_a, RR8);
indev_push_character(instance->kbrdin, data);
}
}
 
/** Initialize z8530. */
z8530_instance_t *z8530_init(z8530_t *dev, inr_t inr, cir_t cir, void *cir_arg)
{
z8530_instance_t *instance
= malloc(sizeof(z8530_instance_t), FRAME_ATOMIC);
if (instance) {
instance->z8530 = dev;
instance->kbrdin = NULL;
irq_initialize(&instance->irq);
instance->irq.devno = device_assign_devno();
instance->irq.inr = inr;
instance->irq.claim = z8530_claim;
instance->irq.handler = z8530_irq_handler;
instance->irq.instance = instance;
instance->irq.cir = cir;
instance->irq.cir_arg = cir_arg;
}
return instance;
}
 
void z8530_wire(z8530_instance_t *instance, indev_t *kbrdin)
{
ASSERT(instance);
ASSERT(kbrdin);
instance->kbrdin = kbrdin;
irq_register(&instance->irq);
(void) z8530_read(&instance->z8530->ctl_a, RR8);
/*
* Clear any pending TX interrupts or we never manage
* to set FHC UART interrupt state to idle.
*/
z8530_write(&instance->z8530->ctl_a, WR0, WR0_TX_IP_RST);
/* interrupt on all characters */
z8530_write(&instance->z8530->ctl_a, WR1, WR1_IARCSC);
/* 8 bits per character and enable receiver */
z8530_write(&instance->z8530->ctl_a, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE);
/* Master Interrupt Enable. */
z8530_write(&instance->z8530->ctl_a, WR9, WR9_MIE);
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/mm/page_ht.c
51,8 → 51,8
#include <adt/hash_table.h>
#include <align.h>
 
static index_t hash(unative_t key[]);
static bool compare(unative_t key[], count_t keys, link_t *item);
static size_t hash(unative_t key[]);
static bool compare(unative_t key[], size_t keys, link_t *item);
static void remove_callback(link_t *item);
 
static void ht_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame,
93,11 → 93,11
*
* @return Index into page hash table.
*/
index_t hash(unative_t key[])
size_t hash(unative_t key[])
{
as_t *as = (as_t *) key[KEY_AS];
uintptr_t page = (uintptr_t) key[KEY_PAGE];
index_t index;
size_t index;
/*
* Virtual page addresses have roughly the same probability
124,7 → 124,7
*
* @return true on match, false otherwise.
*/
bool compare(unative_t key[], count_t keys, link_t *item)
bool compare(unative_t key[], size_t keys, link_t *item)
{
pte_t *t;
 
192,6 → 192,8
t->k = !(flags & PAGE_USER);
t->c = (flags & PAGE_CACHEABLE) != 0;
t->p = !(flags & PAGE_NOT_PRESENT);
t->a = false;
t->d = false;
 
t->as = as;
t->page = ALIGN_DOWN(page, PAGE_SIZE);
/branches/arm/kernel/genarch/src/mm/asid.c
32,7 → 32,7
 
/**
* @file
* @brief ASID management.
* @brief ASID management.
*
* Modern processor architectures optimize TLB utilization
* by using ASIDs (a.k.a. memory contexts on sparc64 and
65,7 → 65,7
#include <adt/list.h>
#include <debug.h>
 
static count_t asids_allocated = 0;
static size_t asids_allocated = 0;
 
/** Allocate free address space identifier.
*
120,7 → 120,7
* of TLB entries (e.g. TSB on sparc64), the
* cache must be invalidated as well.
*/
as_invalidate_translation_cache(as, 0, (count_t) -1);
as_invalidate_translation_cache(as, 0, (size_t) -1);
/*
* Get the system rid of the stolen ASID.
/branches/arm/kernel/genarch/src/kbrd/kbrd.c
0,0 → 1,191
/*
* Copyright (c) 2009 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 genarch
* @{
*/
/**
* @file
* @brief Keyboard processing.
*/
 
#include <genarch/kbrd/kbrd.h>
#include <genarch/kbrd/scanc.h>
 
#ifdef CONFIG_PC_KBD
#include <genarch/kbrd/scanc_pc.h>
#endif
 
#ifdef CONFIG_SUN_KBD
#include <genarch/kbrd/scanc_sun.h>
#endif
 
#ifdef CONFIG_MAC_KBD
#include <genarch/kbrd/scanc_mac.h>
#endif
 
#include <synch/spinlock.h>
#include <console/chardev.h>
#include <console/console.h>
#include <proc/thread.h>
#include <arch.h>
#include <macros.h>
 
#define IGNORE_CODE 0x7f
#define KEY_RELEASE 0x80
 
#define PRESSED_SHIFT (1 << 0)
#define PRESSED_CAPSLOCK (1 << 1)
#define LOCKED_CAPSLOCK (1 << 0)
 
static indev_operations_t kbrd_raw_ops = {
.poll = NULL
};
 
/** Process release of key.
*
* @param sc Scancode of the key being released.
*/
static void key_released(kbrd_instance_t *instance, wchar_t sc)
{
spinlock_lock(&instance->keylock);
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
instance->keyflags &= ~PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
instance->keyflags &= ~PRESSED_CAPSLOCK;
if (instance->lockflags & LOCKED_CAPSLOCK)
instance->lockflags &= ~LOCKED_CAPSLOCK;
else
instance->lockflags |= LOCKED_CAPSLOCK;
break;
default:
break;
}
spinlock_unlock(&instance->keylock);
}
 
/** Process keypress.
*
* @param sc Scancode of the key being pressed.
*/
static void key_pressed(kbrd_instance_t *instance, wchar_t sc)
{
bool letter;
bool shift;
bool capslock;
spinlock_lock(&instance->keylock);
switch (sc) {
case SC_LSHIFT:
case SC_RSHIFT:
instance->keyflags |= PRESSED_SHIFT;
break;
case SC_CAPSLOCK:
instance->keyflags |= PRESSED_CAPSLOCK;
break;
case SC_SCAN_ESCAPE:
break;
default:
letter = islower(sc_primary_map[sc]);
shift = instance->keyflags & PRESSED_SHIFT;
capslock = (instance->keyflags & PRESSED_CAPSLOCK) ||
(instance->lockflags & LOCKED_CAPSLOCK);
if ((letter) && (capslock))
shift = !shift;
if (shift)
indev_push_character(instance->sink, sc_secondary_map[sc]);
else
indev_push_character(instance->sink, sc_primary_map[sc]);
break;
}
spinlock_unlock(&instance->keylock);
}
 
static void kkbrd(void *arg)
{
kbrd_instance_t *instance = (kbrd_instance_t *) arg;
while (true) {
wchar_t sc = indev_pop_character(&instance->raw);
if (sc == IGNORE_CODE)
continue;
if (sc & KEY_RELEASE)
key_released(instance, (sc ^ KEY_RELEASE) & 0x7f);
else
key_pressed(instance, sc & 0x7f);
}
}
 
kbrd_instance_t *kbrd_init(void)
{
kbrd_instance_t *instance
= malloc(sizeof(kbrd_instance_t), FRAME_ATOMIC);
if (instance) {
instance->thread
= thread_create(kkbrd, (void *) instance, TASK, 0, "kkbrd", false);
if (!instance->thread) {
free(instance);
return NULL;
}
instance->sink = NULL;
indev_initialize("kbrd", &instance->raw, &kbrd_raw_ops);
spinlock_initialize(&instance->keylock, "instance_keylock");
instance->keyflags = 0;
instance->lockflags = 0;
}
return instance;
}
 
indev_t *kbrd_wire(kbrd_instance_t *instance, indev_t *sink)
{
ASSERT(instance);
ASSERT(sink);
instance->sink = sink;
thread_ready(instance->thread);
return &instance->raw;
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/kbrd/scanc_mac.c
0,0 → 1,306
/*
* Copyright (c) 2009 Jiri Svoboda
* 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 genarch
* @{
*/
/**
* @file
* @brief Scan codes for Macintosh ADB keyboards.
*/
 
#include <genarch/kbrd/scanc.h>
#include <typedefs.h>
#include <string.h>
 
/** Primary meaning of scancodes. */
wchar_t sc_primary_map[SCANCODES] = {
[0x00] = 'a',
[0x01] = 's',
[0x02] = 'd',
[0x03] = 'f',
[0x04] = 'h',
[0x05] = 'g',
[0x06] = 'z',
[0x07] = 'x',
[0x08] = 'c',
[0x09] = 'v',
[0x0a] = U_SPECIAL,
[0x0b] = 'b',
[0x0c] = 'q',
[0x0d] = 'w',
[0x0e] = 'e',
[0x0f] = 'r',
[0x10] = 'y',
[0x11] = 't',
[0x12] = '1',
[0x13] = '2',
[0x14] = '3',
[0x15] = '4',
[0x16] = '6',
[0x17] = '5',
[0x18] = '=',
[0x19] = '9',
[0x1a] = '7',
[0x1b] = '-',
[0x1c] = '8',
[0x1d] = '0',
[0x1e] = ']',
[0x1f] = 'o',
[0x20] = 'u',
[0x21] = '[',
[0x22] = 'i',
[0x23] = 'p',
[0x24] = '\n', /* Enter */
[0x25] = 'l',
[0x26] = 'j',
[0x27] = '\'',
[0x28] = 'k',
[0x29] = ';',
[0x2a] = '\\',
[0x2b] = ',',
[0x2c] = '/',
[0x2d] = 'n',
[0x2e] = 'm',
[0x2f] = '.',
[0x30] = '\t', /* Tab */
[0x31] = ' ', /* Space */
[0x32] = '`',
[0x33] = '\b', /* Backspace */
[0x34] = U_SPECIAL,
[0x35] = U_ESCAPE,
[0x36] = U_SPECIAL,
[0x37] = U_SPECIAL,
[0x38] = U_SPECIAL,
[0x39] = U_SPECIAL,
[0x3a] = U_SPECIAL,
[0x3b] = U_LEFT_ARROW,
[0x3c] = U_RIGHT_ARROW,
[0x3d] = U_DOWN_ARROW,
[0x3e] = U_UP_ARROW,
[0x3f] = U_SPECIAL,
[0x40] = U_SPECIAL,
[0x41] = '.', /* Num Separator */
[0x42] = U_SPECIAL,
[0x43] = '*', /* Num Times */
[0x44] = U_SPECIAL,
[0x45] = '+', /* Num Plus */
[0x46] = U_SPECIAL,
[0x47] = U_SPECIAL,
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_SPECIAL,
[0x4b] = '/', /* Num Divide */
[0x4c] = U_SPECIAL,
[0x4d] = U_SPECIAL,
[0x4e] = '-', /* Num Minus */
[0x4f] = U_SPECIAL,
[0x50] = U_SPECIAL,
[0x51] = U_SPECIAL,
[0x52] = '0', /* Num Zero */
[0x53] = '1', /* Num One */
[0x54] = '2', /* Num Two */
[0x55] = '3', /* Num Three */
[0x56] = '4', /* Num Four */
[0x57] = '5', /* Num Five */
[0x58] = '6', /* Num Six */
[0x59] = '7', /* Num Seven */
[0x5a] = U_SPECIAL,
[0x5b] = '8', /* Num Eight */
[0x5c] = '9', /* Num Nine */
[0x5d] = U_SPECIAL,
[0x5e] = U_SPECIAL,
[0x5f] = U_SPECIAL,
[0x60] = U_SPECIAL,
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL,
[0x63] = U_SPECIAL,
[0x64] = U_SPECIAL,
[0x65] = U_SPECIAL,
[0x66] = U_SPECIAL,
[0x67] = U_SPECIAL,
[0x68] = U_SPECIAL,
[0x69] = U_SPECIAL,
[0x6a] = U_SPECIAL,
[0x6b] = U_SPECIAL,
[0x6c] = U_SPECIAL,
[0x6d] = U_SPECIAL,
[0x6e] = U_SPECIAL,
[0x6f] = U_SPECIAL,
[0x70] = U_SPECIAL,
[0x71] = U_SPECIAL,
[0x72] = U_SPECIAL,
[0x73] = U_HOME_ARROW,
[0x74] = U_PAGE_UP,
[0x75] = U_DELETE,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL,
[0x78] = U_SPECIAL,
[0x79] = U_PAGE_DOWN,
[0x7a] = U_SPECIAL,
[0x7b] = U_SPECIAL,
[0x7c] = U_SPECIAL,
[0x7d] = U_SPECIAL,
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** Secondary meaning of scancodes. */
wchar_t sc_secondary_map[SCANCODES] = {
[0x00] = 'A',
[0x01] = 'S',
[0x02] = 'D',
[0x03] = 'F',
[0x04] = 'H',
[0x05] = 'G',
[0x06] = 'Z',
[0x07] = 'X',
[0x08] = 'C',
[0x09] = 'V',
[0x0a] = U_SPECIAL,
[0x0b] = 'B',
[0x0c] = 'Q',
[0x0d] = 'W',
[0x0e] = 'E',
[0x0f] = 'R',
[0x10] = 'Y',
[0x11] = 'T',
[0x12] = '!',
[0x13] = '@',
[0x14] = '#',
[0x15] = '$',
[0x16] = '^',
[0x17] = '%',
[0x18] = '+',
[0x19] = '(',
[0x1a] = '&',
[0x1b] = '_',
[0x1c] = '*',
[0x1d] = ')',
[0x1e] = '}',
[0x1f] = 'O',
[0x20] = 'U',
[0x21] = '{',
[0x22] = 'I',
[0x23] = 'P',
[0x24] = '\n', /* Enter */
[0x25] = 'L',
[0x26] = 'J',
[0x27] = '"',
[0x28] = 'K',
[0x29] = ':',
[0x2a] = '|',
[0x2b] = '<',
[0x2c] = '?',
[0x2d] = 'N',
[0x2e] = 'M',
[0x2f] = '>',
[0x30] = '\t', /* Tab */
[0x31] = ' ', /* Space */
[0x32] = '~',
[0x33] = '\b', /* Backspace */
[0x34] = U_SPECIAL,
[0x35] = U_SPECIAL,
[0x36] = U_SPECIAL,
[0x37] = U_SPECIAL,
[0x38] = U_SPECIAL,
[0x39] = U_SPECIAL,
[0x3a] = U_SPECIAL,
[0x3b] = U_SPECIAL,
[0x3c] = U_SPECIAL,
[0x3d] = U_SPECIAL,
[0x3e] = U_SPECIAL,
[0x3f] = U_SPECIAL,
[0x40] = U_SPECIAL,
[0x41] = '.', /* Num Separator */
[0x42] = U_SPECIAL,
[0x43] = '*', /* Num Times */
[0x44] = U_SPECIAL,
[0x45] = '+', /* Num Plus */
[0x46] = U_SPECIAL,
[0x47] = U_SPECIAL,
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_SPECIAL,
[0x4b] = '/', /* Num Divide */
[0x4c] = U_SPECIAL,
[0x4d] = U_SPECIAL,
[0x4e] = '-', /* Num Minus */
[0x4f] = U_SPECIAL,
[0x50] = U_SPECIAL,
[0x51] = U_SPECIAL,
[0x52] = '0', /* Num Zero */
[0x53] = '1', /* Num One */
[0x54] = '2', /* Num Two */
[0x55] = '3', /* Num Three */
[0x56] = '4', /* Num Four */
[0x57] = '5', /* Num Five */
[0x58] = '6', /* Num Six */
[0x59] = '7', /* Num Seven */
[0x5a] = U_SPECIAL,
[0x5b] = '8', /* Num Eight */
[0x5c] = '9', /* Num Nine */
[0x5d] = U_SPECIAL,
[0x5e] = U_SPECIAL,
[0x5f] = U_SPECIAL,
[0x60] = U_SPECIAL,
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL,
[0x63] = U_SPECIAL,
[0x64] = U_SPECIAL,
[0x65] = U_SPECIAL,
[0x66] = U_SPECIAL,
[0x67] = U_SPECIAL,
[0x68] = U_SPECIAL,
[0x69] = U_SPECIAL,
[0x6a] = U_SPECIAL,
[0x6b] = U_SPECIAL,
[0x6c] = U_SPECIAL,
[0x6d] = U_SPECIAL,
[0x6e] = U_SPECIAL,
[0x6f] = U_SPECIAL,
[0x70] = U_SPECIAL,
[0x71] = U_SPECIAL,
[0x72] = U_SPECIAL,
[0x73] = U_SPECIAL,
[0x74] = U_SPECIAL,
[0x75] = U_SPECIAL,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL,
[0x78] = U_SPECIAL,
[0x79] = U_SPECIAL,
[0x7a] = U_SPECIAL,
[0x7b] = U_SPECIAL,
[0x7c] = U_SPECIAL,
[0x7d] = U_SPECIAL,
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** @}
*/
/branches/arm/kernel/genarch/src/kbrd/scanc_pc.c
0,0 → 1,221
/*
* Copyright (c) 2006 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 genarch
* @{
*/
/**
* @file
* @brief Scan codes for PC keyboards.
*/
 
#include <genarch/kbrd/scanc.h>
#include <typedefs.h>
#include <string.h>
 
/** Primary meaning of scancodes. */
wchar_t sc_primary_map[SCANCODES] = {
U_NULL, /* 0x00 - undefined */
U_ESCAPE, /* 0x01 - Esc */
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',
'\b', /* 0x0e - Backspace */
'\t', /* 0x0f - Tab */
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']',
'\n', /* 0x1e - Enter */
U_SPECIAL, /* 0x1d - Left Ctrl */
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`',
U_SPECIAL, /* 0x2a - Left Shift */
'\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/',
U_SPECIAL, /* 0x36 - Right Shift */
U_SPECIAL, /* 0x37 - Print Screen */
U_SPECIAL, /* 0x38 - Left Alt */
' ',
U_SPECIAL, /* 0x3a - CapsLock */
U_SPECIAL, /* 0x3b - F1 */
U_SPECIAL, /* 0x3c - F2 */
U_SPECIAL, /* 0x3d - F3 */
U_SPECIAL, /* 0x3e - F4 */
U_SPECIAL, /* 0x3f - F5 */
U_SPECIAL, /* 0x40 - F6 */
U_SPECIAL, /* 0x41 - F7 */
U_SPECIAL, /* 0x42 - F8 */
U_SPECIAL, /* 0x43 - F9 */
U_SPECIAL, /* 0x44 - F10 */
U_SPECIAL, /* 0x45 - NumLock */
U_SPECIAL, /* 0x46 - ScrollLock */
U_HOME_ARROW, /* 0x47 - Home */
U_UP_ARROW, /* 0x48 - Up Arrow */
U_PAGE_UP, /* 0x49 - Page Up */
'-',
U_LEFT_ARROW, /* 0x4b - Left Arrow */
'5', /* 0x4c - Numpad Center */
U_RIGHT_ARROW, /* 0x4d - Right Arrow */
'+',
U_END_ARROW, /* 0x4f - End */
U_DOWN_ARROW, /* 0x50 - Down Arrow */
U_PAGE_DOWN, /* 0x51 - Page Down */
'0', /* 0x52 - Numpad Insert */
U_DELETE, /* 0x53 - Delete */
U_SPECIAL, /* 0x54 - Alt-SysRq */
U_SPECIAL, /* 0x55 - F11/F12/PF1/FN */
U_SPECIAL, /* 0x56 - unlabelled key next to LAlt */
U_SPECIAL, /* 0x57 - F11 */
U_SPECIAL, /* 0x58 - F12 */
U_SPECIAL, /* 0x59 */
U_SPECIAL, /* 0x5a */
U_SPECIAL, /* 0x5b */
U_SPECIAL, /* 0x5c */
U_SPECIAL, /* 0x5d */
U_SPECIAL, /* 0x5e */
U_SPECIAL, /* 0x5f */
U_SPECIAL, /* 0x60 */
U_SPECIAL, /* 0x61 */
U_SPECIAL, /* 0x62 */
U_SPECIAL, /* 0x63 */
U_SPECIAL, /* 0x64 */
U_SPECIAL, /* 0x65 */
U_SPECIAL, /* 0x66 */
U_SPECIAL, /* 0x67 */
U_SPECIAL, /* 0x68 */
U_SPECIAL, /* 0x69 */
U_SPECIAL, /* 0x6a */
U_SPECIAL, /* 0x6b */
U_SPECIAL, /* 0x6c */
U_SPECIAL, /* 0x6d */
U_SPECIAL, /* 0x6e */
U_SPECIAL, /* 0x6f */
U_SPECIAL, /* 0x70 */
U_SPECIAL, /* 0x71 */
U_SPECIAL, /* 0x72 */
U_SPECIAL, /* 0x73 */
U_SPECIAL, /* 0x74 */
U_SPECIAL, /* 0x75 */
U_SPECIAL, /* 0x76 */
U_SPECIAL, /* 0x77 */
U_SPECIAL, /* 0x78 */
U_SPECIAL, /* 0x79 */
U_SPECIAL, /* 0x7a */
U_SPECIAL, /* 0x7b */
U_SPECIAL, /* 0x7c */
U_SPECIAL, /* 0x7d */
U_SPECIAL, /* 0x7e */
U_SPECIAL /* 0x7f */
};
 
/** Secondary meaning of scancodes. */
wchar_t sc_secondary_map[SCANCODES] = {
U_NULL, /* 0x00 - undefined */
U_ESCAPE, /* 0x01 - Esc */
'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',
'\b', /* 0x0e - Backspace */
'\t', /* 0x0f - Tab */
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}',
'\n', /* 0x1e - Enter */
U_SPECIAL, /* 0x1d - Left Ctrl */
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
U_SPECIAL, /* 0x2a - Left Shift */
'|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?',
U_SPECIAL, /* 0x36 - Right Shift */
U_SPECIAL, /* 0x37 - Print Screen */
U_SPECIAL, /* 0x38 - Left Alt */
' ',
U_SPECIAL, /* 0x3a - CapsLock */
U_SPECIAL, /* 0x3b - F1 */
U_SPECIAL, /* 0x3c - F2 */
U_SPECIAL, /* 0x3d - F3 */
U_SPECIAL, /* 0x3e - F4 */
U_SPECIAL, /* 0x3f - F5 */
U_SPECIAL, /* 0x40 - F6 */
U_SPECIAL, /* 0x41 - F7 */
U_SPECIAL, /* 0x42 - F8 */
U_SPECIAL, /* 0x43 - F9 */
U_SPECIAL, /* 0x44 - F10 */
U_SPECIAL, /* 0x45 - NumLock */
U_SPECIAL, /* 0x46 - ScrollLock */
U_HOME_ARROW, /* 0x47 - Home */
U_UP_ARROW, /* 0x48 - Up Arrow */
U_PAGE_UP, /* 0x49 - Page Up */
'-',
U_LEFT_ARROW, /* 0x4b - Left Arrow */
'5', /* 0x4c - Numpad Center */
U_RIGHT_ARROW, /* 0x4d - Right Arrow */
'+',
U_END_ARROW, /* 0x4f - End */
U_DOWN_ARROW, /* 0x50 - Down Arrow */
U_PAGE_DOWN, /* 0x51 - Page Down */
'0', /* 0x52 - Numpad Insert */
U_DELETE, /* 0x53 - Delete */
U_SPECIAL, /* 0x54 - Alt-SysRq */
U_SPECIAL, /* 0x55 - F11/F12/PF1/FN */
U_SPECIAL, /* 0x56 - unlabelled key next to LAlt */
U_SPECIAL, /* 0x57 - F11 */
U_SPECIAL, /* 0x58 - F12 */
U_SPECIAL, /* 0x59 */
U_SPECIAL, /* 0x5a */
U_SPECIAL, /* 0x5b */
U_SPECIAL, /* 0x5c */
U_SPECIAL, /* 0x5d */
U_SPECIAL, /* 0x5e */
U_SPECIAL, /* 0x5f */
U_SPECIAL, /* 0x60 */
U_SPECIAL, /* 0x61 */
U_SPECIAL, /* 0x62 */
U_SPECIAL, /* 0x63 */
U_SPECIAL, /* 0x64 */
U_SPECIAL, /* 0x65 */
U_SPECIAL, /* 0x66 */
U_SPECIAL, /* 0x67 */
U_SPECIAL, /* 0x68 */
U_SPECIAL, /* 0x69 */
U_SPECIAL, /* 0x6a */
U_SPECIAL, /* 0x6b */
U_SPECIAL, /* 0x6c */
U_SPECIAL, /* 0x6d */
U_SPECIAL, /* 0x6e */
U_SPECIAL, /* 0x6f */
U_SPECIAL, /* 0x70 */
U_SPECIAL, /* 0x71 */
U_SPECIAL, /* 0x72 */
U_SPECIAL, /* 0x73 */
U_SPECIAL, /* 0x74 */
U_SPECIAL, /* 0x75 */
U_SPECIAL, /* 0x76 */
U_SPECIAL, /* 0x77 */
U_SPECIAL, /* 0x78 */
U_SPECIAL, /* 0x79 */
U_SPECIAL, /* 0x7a */
U_SPECIAL, /* 0x7b */
U_SPECIAL, /* 0x7c */
U_SPECIAL, /* 0x7d */
U_SPECIAL, /* 0x7e */
U_SPECIAL /* 0x7f */
};
 
/** @}
*/
/branches/arm/kernel/genarch/src/kbrd/scanc_sun.c
0,0 → 1,306
/*
* Copyright (c) 2006 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 genarch
* @{
*/
/**
* @file
* @brief Scan codes for Sun keyboards.
*/
 
#include <genarch/kbrd/scanc.h>
#include <typedefs.h>
#include <string.h>
 
/** Primary meaning of scancodes. */
wchar_t sc_primary_map[SCANCODES] = {
[0x00] = U_SPECIAL,
[0x01] = U_SPECIAL,
[0x02] = U_SPECIAL,
[0x03] = U_SPECIAL,
[0x04] = U_SPECIAL,
[0x05] = U_SPECIAL, /* F1 */
[0x06] = U_SPECIAL, /* F2 */
[0x07] = U_SPECIAL, /* F10 */
[0x08] = U_SPECIAL, /* F3 */
[0x09] = U_SPECIAL, /* F11 */
[0x0a] = U_SPECIAL, /* F4 */
[0x0b] = U_SPECIAL, /* F12 */
[0x0c] = U_SPECIAL, /* F5 */
[0x0d] = U_SPECIAL, /* Right Alt */
[0x0e] = U_SPECIAL, /* F6 */
[0x0f] = U_SPECIAL,
[0x10] = U_SPECIAL, /* F7 */
[0x11] = U_SPECIAL, /* F8 */
[0x12] = U_SPECIAL, /* F9 */
[0x13] = U_SPECIAL, /* Left Alt */
[0x14] = U_UP_ARROW, /* Up Arrow */
[0x15] = U_SPECIAL, /* Pause */
[0x16] = U_SPECIAL,
[0x17] = U_SPECIAL, /* Scroll Lock */
[0x18] = U_LEFT_ARROW, /* Left Arrow */
[0x19] = U_SPECIAL,
[0x1a] = U_SPECIAL,
[0x1b] = U_DOWN_ARROW, /* Down Arrow */
[0x1c] = U_RIGHT_ARROW, /* Right Arrow */
[0x1d] = U_ESCAPE, /* Esc */
[0x1e] = '1',
[0x1f] = '2',
[0x20] = '3',
[0x21] = '4',
[0x22] = '5',
[0x23] = '6',
[0x24] = '7',
[0x25] = '8',
[0x26] = '9',
[0x27] = '0',
[0x28] = '-',
[0x29] = '=',
[0x2a] = '`',
[0x2b] = '\b', /* Backspace */
[0x2c] = U_SPECIAL, /* Insert */
[0x2d] = U_SPECIAL,
[0x2e] = '/', /* Numpad / */
[0x2f] = '*', /* Numpad * */
[0x30] = U_SPECIAL,
[0x31] = U_SPECIAL,
[0x32] = '.', /* Numpad . */
[0x33] = U_SPECIAL,
[0x34] = U_HOME_ARROW, /* Home */
[0x35] = '\t', /* Tab */
[0x36] = 'q',
[0x37] = 'w',
[0x38] = 'e',
[0x39] = 'r',
[0x3a] = 't',
[0x3b] = 'y',
[0x3c] = 'u',
[0x3d] = 'i',
[0x3e] = 'o',
[0x3f] = 'p',
[0x40] = '[',
[0x41] = ']',
[0x42] = U_DELETE, /* Delete */
[0x43] = U_SPECIAL,
[0x44] = '7', /* Numpad 7 */
[0x45] = '8', /* Numpad 8 */
[0x46] = '9', /* Numpad 9 */
[0x47] = '-', /* Numpad - */
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_END_ARROW, /* End */
[0x4b] = U_SPECIAL,
[0x4c] = U_SPECIAL, /* Control */
[0x4d] = 'a',
[0x4e] = 's',
[0x4f] = 'd',
[0x50] = 'f',
[0x51] = 'g',
[0x52] = 'h',
[0x53] = 'j',
[0x54] = 'k',
[0x55] = 'l',
[0x56] = ';',
[0x57] = '\'',
[0x58] = '\\',
[0x59] = '\n', /* Enter */
[0x5a] = '\n', /* Numpad Enter */
[0x5b] = '4', /* Numpad 4 */
[0x5c] = '5', /* Numpad 5 */
[0x5d] = '6', /* Numpad 6 */
[0x5e] = '0', /* Numpad 0 */
[0x5f] = U_SPECIAL,
[0x60] = U_PAGE_UP, /* Page Up */
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL, /* NumLock */
[0x63] = U_SPECIAL, /* Left Shift */
[0x64] = 'z',
[0x65] = 'x',
[0x66] = 'c',
[0x67] = 'v',
[0x68] = 'b',
[0x69] = 'n',
[0x6a] = 'm',
[0x6b] = ',',
[0x6c] = '.',
[0x6d] = '/',
[0x6e] = U_SPECIAL, /* Right Shift */
[0x6f] = U_SPECIAL,
[0x70] = '1', /* Numpad 1 */
[0x71] = '2', /* Numpad 2 */
[0x72] = '3', /* Numpad 3 */
[0x73] = U_SPECIAL,
[0x74] = U_SPECIAL,
[0x75] = U_SPECIAL,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL, /* CapsLock */
[0x78] = U_SPECIAL,
[0x79] = ' ',
[0x7a] = U_SPECIAL,
[0x7b] = U_PAGE_DOWN, /* Page Down */
[0x7c] = U_SPECIAL,
[0x7d] = '+', /* Numpad + */
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** Secondary meaning of scancodes. */
wchar_t sc_secondary_map[SCANCODES] = {
[0x00] = U_SPECIAL,
[0x01] = U_SPECIAL,
[0x02] = U_SPECIAL,
[0x03] = U_SPECIAL,
[0x04] = U_SPECIAL,
[0x05] = U_SPECIAL, /* F1 */
[0x06] = U_SPECIAL, /* F2 */
[0x07] = U_SPECIAL, /* F10 */
[0x08] = U_SPECIAL, /* F3 */
[0x09] = U_SPECIAL, /* F11 */
[0x0a] = U_SPECIAL, /* F4 */
[0x0b] = U_SPECIAL, /* F12 */
[0x0c] = U_SPECIAL, /* F5 */
[0x0d] = U_SPECIAL, /* Right Alt */
[0x0e] = U_SPECIAL, /* F6 */
[0x0f] = U_SPECIAL,
[0x10] = U_SPECIAL, /* F7 */
[0x11] = U_SPECIAL, /* F8 */
[0x12] = U_SPECIAL, /* F9 */
[0x13] = U_SPECIAL, /* Left Alt */
[0x14] = U_UP_ARROW, /* Up Arrow */
[0x15] = U_SPECIAL, /* Pause */
[0x16] = U_SPECIAL,
[0x17] = U_SPECIAL, /* Scroll Lock */
[0x18] = U_LEFT_ARROW, /* Left Arrow */
[0x19] = U_SPECIAL,
[0x1a] = U_SPECIAL,
[0x1b] = U_DOWN_ARROW, /* Down Arrow */
[0x1c] = U_RIGHT_ARROW, /* Right Arrow */
[0x1d] = U_ESCAPE, /* Esc */
[0x1e] = '!',
[0x1f] = '@',
[0x20] = '#',
[0x21] = '$',
[0x22] = '%',
[0x23] = '^',
[0x24] = '&',
[0x25] = '*',
[0x26] = '(',
[0x27] = ')',
[0x28] = '_',
[0x29] = '+',
[0x2a] = '~',
[0x2b] = '\b', /* Backspace */
[0x2c] = U_SPECIAL, /* Insert */
[0x2d] = U_SPECIAL,
[0x2e] = '/', /* Numpad / */
[0x2f] = '*', /* Numpad * */
[0x30] = U_SPECIAL,
[0x31] = U_SPECIAL,
[0x32] = '.', /* Numpad . */
[0x33] = U_SPECIAL,
[0x34] = U_HOME_ARROW, /* Home */
[0x35] = '\t', /* Tab */
[0x36] = 'Q',
[0x37] = 'W',
[0x38] = 'E',
[0x39] = 'R',
[0x3a] = 'T',
[0x3b] = 'Y',
[0x3c] = 'U',
[0x3d] = 'I',
[0x3e] = 'O',
[0x3f] = 'P',
[0x40] = '{',
[0x41] = '}',
[0x42] = U_DELETE, /* Delete */
[0x43] = U_SPECIAL,
[0x44] = '7', /* Numpad 7 */
[0x45] = '8', /* Numpad 8 */
[0x46] = '9', /* Numpad 9 */
[0x47] = '-', /* Numpad - */
[0x48] = U_SPECIAL,
[0x49] = U_SPECIAL,
[0x4a] = U_END_ARROW, /* End */
[0x4b] = U_SPECIAL,
[0x4c] = U_SPECIAL, /* Control */
[0x4d] = 'A',
[0x4e] = 'S',
[0x4f] = 'D',
[0x50] = 'F',
[0x51] = 'G',
[0x52] = 'H',
[0x53] = 'J',
[0x54] = 'K',
[0x55] = 'L',
[0x56] = ':',
[0x57] = '"',
[0x58] = '|',
[0x59] = '\n', /* Enter */
[0x5a] = '\n', /* Numpad Enter */
[0x5b] = '4', /* Numpad 4 */
[0x5c] = '5', /* Numpad 5 */
[0x5d] = '6', /* Numpad 6 */
[0x5e] = '0', /* Numpad 0 */
[0x5f] = U_SPECIAL,
[0x60] = U_PAGE_UP, /* Page Up */
[0x61] = U_SPECIAL,
[0x62] = U_SPECIAL, /* NumLock */
[0x63] = U_SPECIAL, /* Left Shift */
[0x64] = 'Z',
[0x65] = 'X',
[0x66] = 'C',
[0x67] = 'V',
[0x68] = 'B',
[0x69] = 'N',
[0x6a] = 'M',
[0x6b] = '<',
[0x6c] = '>',
[0x6d] = '?',
[0x6e] = U_SPECIAL, /* Right Shift */
[0x6f] = U_SPECIAL,
[0x70] = '1', /* Numpad 1 */
[0x71] = '2', /* Numpad 2 */
[0x72] = '3', /* Numpad 3 */
[0x73] = U_SPECIAL,
[0x74] = U_SPECIAL,
[0x75] = U_SPECIAL,
[0x76] = U_SPECIAL,
[0x77] = U_SPECIAL, /* CapsLock */
[0x78] = U_SPECIAL,
[0x79] = ' ',
[0x7a] = U_SPECIAL,
[0x7b] = U_PAGE_DOWN, /* Page Down */
[0x7c] = U_SPECIAL,
[0x7d] = '+', /* Numpad + */
[0x7e] = U_SPECIAL,
[0x7f] = U_SPECIAL
};
 
/** @}
*/
/branches/arm/kernel/genarch/src/kbrd
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/acpi/acpi.c
49,8 → 49,12
struct acpi_rsdt *acpi_rsdt = NULL;
struct acpi_xsdt *acpi_xsdt = NULL;
 
struct acpi_signature_map signature_map[] = {
{ (uint8_t *)"APIC", (void *) &acpi_madt, "Multiple APIC Description Table" }
struct acpi_signature_map signature_map[] = {
{
(uint8_t *) "APIC",
(void *) &acpi_madt,
"Multiple APIC Description Table"
}
};
 
static int rsdp_check(uint8_t *rsdp) {
105,7 → 109,7
if (!acpi_sdt_check((uint8_t *) h))
goto next;
*signature_map[j].sdt_ptr = h;
printf("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
}
}
next:
126,7 → 130,7
if (!acpi_sdt_check((uint8_t *) h))
goto next;
*signature_map[j].sdt_ptr = h;
printf("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description);
}
}
next:
160,13 → 164,16
return;
 
rsdp_found:
printf("%p: ACPI Root System Description Pointer\n", acpi_rsdp);
LOG("%p: ACPI Root System Description Pointer\n", acpi_rsdp);
 
acpi_rsdt = (struct acpi_rsdt *) (unative_t) acpi_rsdp->rsdt_address;
if (acpi_rsdp->revision) acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address);
if (acpi_rsdp->revision)
acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address);
 
if (acpi_rsdt) map_sdt((struct acpi_sdt_header *) acpi_rsdt);
if (acpi_xsdt) map_sdt((struct acpi_sdt_header *) acpi_xsdt);
if (acpi_rsdt)
map_sdt((struct acpi_sdt_header *) acpi_rsdt);
if (acpi_xsdt)
map_sdt((struct acpi_sdt_header *) acpi_xsdt);
 
if (acpi_rsdt && !acpi_sdt_check((uint8_t *) acpi_rsdt)) {
printf("RSDT: bad checksum\n");
177,8 → 184,10
return;
}
 
if (acpi_xsdt) configure_via_xsdt();
else if (acpi_rsdt) configure_via_rsdt();
if (acpi_xsdt)
configure_via_xsdt();
else if (acpi_rsdt)
configure_via_rsdt();
 
}
 
/branches/arm/kernel/genarch/src/acpi/madt.c
62,11 → 62,11
struct madt_l_apic *madt_l_apic_entries = NULL;
struct madt_io_apic *madt_io_apic_entries = NULL;
 
index_t madt_l_apic_entry_index = 0;
index_t madt_io_apic_entry_index = 0;
count_t madt_l_apic_entry_cnt = 0;
count_t madt_io_apic_entry_cnt = 0;
count_t cpu_count = 0;
size_t madt_l_apic_entry_index = 0;
size_t madt_io_apic_entry_index = 0;
size_t madt_l_apic_entry_cnt = 0;
size_t madt_io_apic_entry_cnt = 0;
size_t cpu_count = 0;
 
struct madt_apic_header * * madt_entries_index = NULL;
unsigned int madt_entries_index_cnt = 0;
86,10 → 86,10
/*
* ACPI MADT Implementation of SMP configuration interface.
*/
static count_t madt_cpu_count(void);
static bool madt_cpu_enabled(index_t i);
static bool madt_cpu_bootstrap(index_t i);
static uint8_t madt_cpu_apic_id(index_t i);
static size_t madt_cpu_count(void);
static bool madt_cpu_enabled(size_t i);
static bool madt_cpu_bootstrap(size_t i);
static uint8_t madt_cpu_apic_id(size_t i);
static int madt_irq_to_pin(unsigned int irq);
 
struct smp_config_operations madt_config_operations = {
100,12 → 100,12
.irq_to_pin = madt_irq_to_pin
};
 
count_t madt_cpu_count(void)
size_t madt_cpu_count(void)
{
return madt_l_apic_entry_cnt;
}
 
bool madt_cpu_enabled(index_t i)
bool madt_cpu_enabled(size_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->flags & 0x1;
112,13 → 112,13
 
}
 
bool madt_cpu_bootstrap(index_t i)
bool madt_cpu_bootstrap(size_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id == l_apic_id();
}
 
uint8_t madt_cpu_apic_id(index_t i)
uint8_t madt_cpu_apic_id(size_t i)
{
ASSERT(i < madt_l_apic_entry_cnt);
return ((struct madt_l_apic *) madt_entries_index[madt_l_apic_entry_index + i])->apic_id;
/branches/arm/kernel/genarch/src/ofw/ebus.c
38,17 → 38,18
#include <genarch/ofw/ofw_tree.h>
#include <arch/memstr.h>
#include <arch/trap/interrupt.h>
#include <func.h>
#include <string.h>
#include <panic.h>
#include <debug.h>
#include <macros.h>
 
/** Apply EBUS ranges to EBUS register. */
bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa)
bool
ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa)
{
ofw_tree_property_t *prop;
ofw_ebus_range_t *range;
count_t ranges;
size_t ranges;
 
prop = ofw_tree_getprop(node, "ranges");
if (!prop)
62,11 → 63,13
for (i = 0; i < ranges; i++) {
if (reg->space != range[i].child_space)
continue;
if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
if (overlaps(reg->addr, reg->size, range[i].child_base,
range[i].size)) {
ofw_pci_reg_t pci_reg;
pci_reg.space = range[i].parent_space;
pci_reg.addr = range[i].parent_base + (reg->addr - range[i].child_base);
pci_reg.addr = range[i].parent_base +
(reg->addr - range[i].child_base);
pci_reg.size = reg->size;
return ofw_pci_apply_ranges(node->parent, &pci_reg, pa);
76,7 → 79,9
return false;
}
 
bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr)
bool
ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg,
uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg)
{
ofw_tree_property_t *prop;
ofw_tree_node_t *controller;
86,7 → 91,7
return false;
 
ofw_ebus_intr_map_t *intr_map = prop->value;
count_t count = prop->size / sizeof(ofw_ebus_intr_map_t);
size_t count = prop->size / sizeof(ofw_ebus_intr_map_t);
ASSERT(count);
104,8 → 109,8
unsigned int i;
for (i = 0; i < count; i++) {
if ((intr_map[i].space == space) && (intr_map[i].addr == addr)
&& (intr_map[i].intr == intr))
if ((intr_map[i].space == space) &&
(intr_map[i].addr == addr) && (intr_map[i].intr == intr))
goto found;
}
return false;
113,14 → 118,16
found:
/*
* We found the device that functions as an interrupt controller
* for the interrupt. We also found partial mapping from interrupt to INO.
* for the interrupt. We also found partial mapping from interrupt to
* INO.
*/
 
controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), intr_map[i].controller_handle);
controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"),
intr_map[i].controller_handle);
if (!controller)
return false;
if (strcmp(ofw_tree_node_name(controller), "pci") != 0) {
if (str_cmp(ofw_tree_node_name(controller), "pci") != 0) {
/*
* This is not a PCI node.
*/
130,7 → 137,8
/*
* Let the PCI do the next step in mapping the interrupt.
*/
if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino, inr))
if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino,
inr, cir, cir_arg))
return false;
 
return true;
/branches/arm/kernel/genarch/src/ofw/fhc.c
38,7 → 38,7
#include <genarch/ofw/ofw_tree.h>
#include <arch/drivers/fhc.h>
#include <arch/memstr.h>
#include <func.h>
#include <string.h>
#include <panic.h>
#include <macros.h>
 
46,7 → 46,7
{
ofw_tree_property_t *prop;
ofw_fhc_range_t *range;
count_t ranges;
size_t ranges;
 
prop = ofw_tree_getprop(node, "ranges");
if (!prop)
66,8 → 66,8
*pa = addr;
return true;
}
if (strcmp(ofw_tree_node_name(node->parent), "central") != 0)
panic("Unexpected parent node: %s.\n", ofw_tree_node_name(node->parent));
if (str_cmp(ofw_tree_node_name(node->parent), "central") != 0)
panic("Unexpected parent node: %s.", ofw_tree_node_name(node->parent));
ofw_central_reg_t central_reg;
84,11 → 84,11
bool ofw_central_apply_ranges(ofw_tree_node_t *node, ofw_central_reg_t *reg, uintptr_t *pa)
{
if (node->parent->parent)
panic("Unexpected parent node: %s.\n", ofw_tree_node_name(node->parent));
panic("Unexpected parent node: %s.", ofw_tree_node_name(node->parent));
ofw_tree_property_t *prop;
ofw_central_range_t *range;
count_t ranges;
size_t ranges;
prop = ofw_tree_getprop(node, "ranges");
if (!prop)
109,7 → 109,9
return false;
}
 
bool ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *inr)
bool
ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg,
uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg)
{
fhc_t *fhc = NULL;
if (!node->device) {
126,6 → 128,8
fhc_enable_interrupt(fhc, interrupt);
*inr = interrupt;
*cir = fhc_clear_interrupt;
*cir_arg = fhc;
return true;
}
 
/branches/arm/kernel/genarch/src/ofw/ofw_tree.c
38,7 → 38,7
#include <genarch/ofw/ofw_tree.h>
#include <arch/memstr.h>
#include <mm/slab.h>
#include <func.h>
#include <string.h>
#include <print.h>
#include <panic.h>
 
54,17 → 54,19
 
/** Get OpenFirmware node property.
*
* @param node Node in which to lookup the property.
* @param name Name of the property.
* @param node Node in which to lookup the property.
* @param name Name of the property.
*
* @return Pointer to the property structure or NULL if no such property.
* @return Pointer to the property structure or NULL if no such
* property.
*/
ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name)
ofw_tree_property_t *
ofw_tree_getprop(const ofw_tree_node_t *node, const char *name)
{
unsigned int i;
for (i = 0; i < node->properties; i++) {
if (strcmp(node->property[i].name, name) == 0)
if (str_cmp(node->property[i].name, name) == 0)
return &node->property[i];
}
 
73,9 → 75,9
 
/** Return value of the 'name' property.
*
* @param node Node of interest.
* @param node Node of interest.
*
* @return Value of the 'name' property belonging to the node.
* @return Value of the 'name' property belonging to the node.
*/
const char *ofw_tree_node_name(const ofw_tree_node_t *node)
{
83,10 → 85,10
prop = ofw_tree_getprop(node, "name");
if (!prop)
panic("Node without name property.\n");
panic("Node without name property.");
if (prop->size < 2)
panic("Invalid name property.\n");
panic("Invalid name property.");
return prop->value;
}
93,10 → 95,11
 
/** Lookup child of given name.
*
* @param node Node whose child is being looked up.
* @param name Name of the child being looked up.
* @param node Node whose child is being looked up.
* @param name Name of the child being looked up.
*
* @return NULL if there is no such child or pointer to the matching child node.
* @return NULL if there is no such child or pointer to the
* matching child node.
*/
ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name)
{
106,7 → 109,7
* Try to find the disambigued name.
*/
for (cur = node->child; cur; cur = cur->peer) {
if (strcmp(cur->da_name, name) == 0)
if (str_cmp(cur->da_name, name) == 0)
return cur;
}
118,7 → 121,7
* are not always fully-qualified.
*/
for (cur = node->child; cur; cur = cur->peer) {
if (strcmp(ofw_tree_node_name(cur), name) == 0)
if (str_cmp(ofw_tree_node_name(cur), name) == 0)
return cur;
}
127,12 → 130,14
 
/** Lookup first child of given device type.
*
* @param node Node whose child is being looked up.
* @param name Device type of the child being looked up.
* @param node Node whose child is being looked up.
* @param name Device type of the child being looked up.
*
* @return NULL if there is no such child or pointer to the matching child node.
* @return NULL if there is no such child or pointer to the
* matching child node.
*/
ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name)
ofw_tree_node_t *
ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name)
{
ofw_tree_node_t *cur;
ofw_tree_property_t *prop;
141,7 → 146,7
prop = ofw_tree_getprop(cur, "device_type");
if (!prop || !prop->value)
continue;
if (strcmp(prop->value, name) == 0)
if (str_cmp(prop->value, name) == 0)
return cur;
}
153,12 → 158,14
* Child nodes are looked up recursively contrary to peer nodes that
* are looked up iteratively to avoid stack overflow.
*
* @param root Root of the searched subtree.
* @param handle OpenFirmware handle.
* @param root Root of the searched subtree.
* @param handle OpenFirmware handle.
*
* @return NULL if there is no such node or pointer to the matching node.
* @return NULL if there is no such node or pointer to the matching
* node.
*/
ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle)
ofw_tree_node_t *
ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle)
{
ofw_tree_node_t *cur;
 
180,12 → 187,14
 
/** Lookup first peer of given device type.
*
* @param node Node whose peer is being looked up.
* @param name Device type of the child being looked up.
* @param node Node whose peer is being looked up.
* @param name Device type of the child being looked up.
*
* @return NULL if there is no such child or pointer to the matching child node.
* @return NULL if there is no such child or pointer to the
* matching child node.
*/
ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name)
ofw_tree_node_t *
ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name)
{
ofw_tree_node_t *cur;
ofw_tree_property_t *prop;
194,7 → 203,7
prop = ofw_tree_getprop(cur, "device_type");
if (!prop || !prop->value)
continue;
if (strcmp(prop->value, name) == 0)
if (str_cmp(prop->value, name) == 0)
return cur;
}
202,29 → 211,57
}
 
 
/** Lookup first peer of given name.
*
* @param node Node whose peer is being looked up.
* @param name Name of the child being looked up.
*
* @return NULL if there is no such peer or pointer to the matching
* peer node.
*/
ofw_tree_node_t *
ofw_tree_find_peer_by_name(ofw_tree_node_t *node, const char *name)
{
ofw_tree_node_t *cur;
ofw_tree_property_t *prop;
for (cur = node->peer; cur; cur = cur->peer) {
prop = ofw_tree_getprop(cur, "name");
if (!prop || !prop->value)
continue;
if (str_cmp(prop->value, name) == 0)
return cur;
}
return NULL;
}
 
/** Lookup OpenFirmware node by its path.
*
* @param path Path to the node.
* @param path Path to the node.
*
* @return NULL if there is no such node or pointer to the leaf node.
* @return NULL if there is no such node or pointer to the leaf
* node.
*/
ofw_tree_node_t *ofw_tree_lookup(const char *path)
{
char buf[NAME_BUF_LEN+1];
char buf[NAME_BUF_LEN + 1];
ofw_tree_node_t *node = ofw_root;
index_t i, j;
size_t i;
size_t j;
if (path[0] != '/')
return NULL;
for (i = 1; i < strlen(path) && node; i = j + 1) {
for (j = i; j < strlen(path) && path[j] != '/'; j++)
;
if (i == j) /* skip extra slashes */
for (i = 1; (i < str_size(path)) && (node); i = j + 1) {
for (j = i; (j < str_size(path)) && (path[j] != '/'); j++);
/* Skip extra slashes */
if (i == j)
continue;
memcpy(buf, &path[i], j - i);
buf[j - i] = '\0';
buf[j - i] = 0;
node = ofw_tree_find_child(node, buf);
}
236,8 → 273,8
* Child nodes are processed recursively and peer nodes are processed
* iteratively in order to avoid stack overflow.
*
* @param node Root of the subtree.
* @param path Current path, NULL for the very root of the entire tree.
* @param node Root of the subtree.
* @param path Current path, NULL for the very root of the entire tree.
*/
static void ofw_tree_node_print(const ofw_tree_node_t *node, const char *path)
{
/branches/arm/kernel/genarch/src/ofw/pci.c
39,7 → 39,7
#include <arch/drivers/pci.h>
#include <arch/trap/interrupt.h>
#include <arch/memstr.h>
#include <func.h>
#include <string.h>
#include <panic.h>
#include <macros.h>
 
49,15 → 49,16
 
#define PCI_IGN 0x1f
 
bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa)
bool
ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa)
{
ofw_tree_property_t *prop;
ofw_pci_range_t *range;
count_t ranges;
size_t ranges;
 
prop = ofw_tree_getprop(node, "ranges");
if (!prop) {
if (strcmp(ofw_tree_node_name(node->parent), "pci") == 0)
if (str_cmp(ofw_tree_node_name(node->parent), "pci") == 0)
return ofw_pci_apply_ranges(node->parent, reg, pa);
return false;
}
68,10 → 69,13
unsigned int i;
for (i = 0; i < ranges; i++) {
if ((reg->space & PCI_SPACE_MASK) != (range[i].space & PCI_SPACE_MASK))
if ((reg->space & PCI_SPACE_MASK) !=
(range[i].space & PCI_SPACE_MASK))
continue;
if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) {
*pa = range[i].parent_base + (reg->addr - range[i].child_base);
if (overlaps(reg->addr, reg->size, range[i].child_base,
range[i].size)) {
*pa = range[i].parent_base +
(reg->addr - range[i].child_base);
return true;
}
}
79,7 → 83,9
return false;
}
 
bool ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, ofw_pci_reg_t *out)
bool
ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg,
ofw_pci_reg_t *out)
{
if (reg->space & PCI_ABS_MASK) {
/* already absolute */
91,11 → 97,11
ofw_tree_property_t *prop;
ofw_pci_reg_t *assigned_address;
count_t assigned_addresses;
size_t assigned_addresses;
prop = ofw_tree_getprop(node, "assigned-addresses");
if (!prop)
panic("Can't find \"assigned-addresses\" property.\n");
panic("Cannot find 'assigned-addresses' property.");
assigned_addresses = prop->size / sizeof(ofw_pci_reg_t);
assigned_address = prop->value;
103,7 → 109,8
unsigned int i;
for (i = 0; i < assigned_addresses; i++) {
if ((assigned_address[i].space & PCI_REG_MASK) == (reg->space & PCI_REG_MASK)) {
if ((assigned_address[i].space & PCI_REG_MASK) ==
(reg->space & PCI_REG_MASK)) {
out->space = assigned_address[i].space;
out->addr = reg->addr + assigned_address[i].addr;
out->size = reg->size;
119,7 → 126,9
* So far, we only know how to map interrupts of non-PCI devices connected
* to a PCI bridge.
*/
bool ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, int *inr)
bool
ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino,
int *inr, cir_t *cir, void **cir_arg)
{
pci_t *pci = node->device;
if (!pci) {
132,6 → 141,8
pci_enable_interrupt(pci, ino);
 
*inr = (PCI_IGN << IGN_SHIFT) | ino;
*cir = pci_clear_interrupt;
*cir_arg = pci;
 
return true;
}
/branches/arm/kernel/genarch/src/ofw/sbus.c
43,7 → 43,7
{
ofw_tree_property_t *prop;
ofw_sbus_range_t *range;
count_t ranges;
size_t ranges;
/*
* The SBUS support is very rudimentary in that we simply assume
/branches/arm/kernel/genarch/src/srln/srln.c
0,0 → 1,159
/*
* Copyright (c) 2009 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 genarch
* @{
*/
/**
* @file
* @brief Serial line processing.
*/
 
#include <genarch/srln/srln.h>
#include <console/chardev.h>
#include <console/console.h>
#include <proc/thread.h>
#include <arch.h>
#include <string.h>
 
static indev_operations_t srln_raw_ops = {
.poll = NULL
};
 
static void ksrln(void *arg)
{
srln_instance_t *instance = (srln_instance_t *) arg;
bool cr = false;
uint32_t escape = 0;
while (true) {
wchar_t ch = indev_pop_character(&instance->raw);
/* ANSI escape sequence processing */
if (escape != 0) {
escape <<= 8;
escape |= ch & 0xff;
if ((escape == 0x1b4f) || (escape == 0x1b5b) || (escape == 0x1b5b33))
continue;
switch (escape) {
case 0x1b4f46:
case 0x1b5b46:
ch = U_END_ARROW;
escape = 0;
break;
case 0x1b4f48:
case 0x1b5b48:
ch = U_HOME_ARROW;
escape = 0;
break;
case 0x1b5b41:
ch = U_UP_ARROW;
escape = 0;
break;
case 0x1b5b42:
ch = U_DOWN_ARROW;
escape = 0;
break;
case 0x1b5b43:
ch = U_RIGHT_ARROW;
escape = 0;
break;
case 0x1b5b44:
ch = U_LEFT_ARROW;
escape = 0;
break;
case 0x1b5b337e:
ch = U_DELETE;
escape = 0;
break;
default:
escape = 0;
}
}
if (ch == 0x1b) {
escape = ch & 0xff;
continue;
}
/* Replace carriage return with line feed
and suppress any following line feed */
if ((ch == '\n') && (cr)) {
cr = false;
continue;
}
if (ch == '\r') {
ch = '\n';
cr = true;
} else
cr = false;
/* Backspace */
if (ch == 0x7f)
ch = '\b';
indev_push_character(instance->sink, ch);
}
}
 
srln_instance_t *srln_init(void)
{
srln_instance_t *instance
= malloc(sizeof(srln_instance_t), FRAME_ATOMIC);
if (instance) {
instance->thread
= thread_create(ksrln, (void *) instance, TASK, 0, "ksrln", false);
if (!instance->thread) {
free(instance);
return NULL;
}
instance->sink = NULL;
indev_initialize("srln", &instance->raw, &srln_raw_ops);
}
return instance;
}
 
indev_t *srln_wire(srln_instance_t *instance, indev_t *sink)
{
ASSERT(instance);
ASSERT(sink);
instance->sink = sink;
thread_ready(instance->thread);
return &instance->raw;
}
 
/** @}
*/
/branches/arm/kernel/genarch/src/multiboot/multiboot.c
0,0 → 1,139
/*
* Copyright (c) 2009 Jiri Svoboda
* 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 genarch
* @{
*/
/** @file
*/
 
#include <genarch/multiboot/multiboot.h>
#include <arch/types.h>
#include <typedefs.h>
#include <config.h>
#include <string.h>
#include <macros.h>
 
/** Extract command name from the multiboot module command line.
*
* @param buf Destination buffer (will always NULL-terminate).
* @param sz Size of destination buffer (in bytes).
* @param cmd_line Input string (the command line).
*
*/
static void extract_command(char *buf, size_t sz, const char *cmd_line)
{
/* Find the first space. */
const char *end = str_chr(cmd_line, ' ');
if (end == NULL)
end = cmd_line + str_size(cmd_line);
/*
* Find last occurence of '/' before 'end'. If found, place start at
* next character. Otherwise, place start at beginning of buffer.
*/
const char *cp = end;
const char *start = buf;
while (cp != start) {
if (*cp == '/') {
start = cp + 1;
break;
}
cp--;
}
/* Copy the command. */
str_ncpy(buf, sz, start, (size_t) (end - start));
}
 
/** Parse multiboot information structure.
*
* If @a signature does not contain a valid multiboot signature,
* assumes no multiboot information is available.
*
* @param signature Should contain the multiboot signature.
* @param mi Pointer to the multiboot information structure.
*/
void multiboot_info_parse(uint32_t signature, const multiboot_info_t *mi)
{
uint32_t flags;
if (signature == MULTIBOOT_LOADER_MAGIC)
flags = mi->flags;
else {
/* No multiboot info available. */
flags = 0;
}
/* Copy module information. */
uint32_t i;
if ((flags & MBINFO_FLAGS_MODS) != 0) {
init.cnt = min(mi->mods_count, CONFIG_INIT_TASKS);
multiboot_mod_t *mods
= (multiboot_mod_t *) MULTIBOOT_PTR(mi->mods_addr);
for (i = 0; i < init.cnt; i++) {
init.tasks[i].addr = PA2KA(mods[i].start);
init.tasks[i].size = mods[i].end - mods[i].start;
/* Copy command line, if available. */
if (mods[i].string) {
extract_command(init.tasks[i].name,
CONFIG_TASK_NAME_BUFLEN,
MULTIBOOT_PTR(mods[i].string));
} else
init.tasks[i].name[0] = 0;
}
} else
init.cnt = 0;
/* Copy memory map. */
if ((flags & MBINFO_FLAGS_MMAP) != 0) {
int32_t mmap_length = mi->mmap_length;
multiboot_mmap_t *mme = MULTIBOOT_PTR(mi->mmap_addr);
e820counter = 0;
i = 0;
while ((mmap_length > 0) && (i < MEMMAP_E820_MAX_RECORDS)) {
e820table[i++] = mme->mm_info;
/* Compute address of next structure. */
uint32_t size = sizeof(mme->size) + mme->size;
mme = ((void *) mme) + size;
mmap_length -= size;
}
e820counter = i;
} else
e820counter = 0;
}
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/src/fb/helenos.xbm
File deleted
/branches/arm/kernel/genarch/src/fb/fb.c
1,4 → 1,5
/*
* Copyright (c) 2008 Martin Decky
* Copyright (c) 2006 Ondrej Palkovsky
* All rights reserved.
*
26,7 → 27,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
/** @addtogroup genarch
* @{
*/
/** @file
33,6 → 34,7
*/
 
#include <genarch/fb/font-8x16.h>
#include <genarch/fb/logo-196x66.h>
#include <genarch/fb/visuals.h>
#include <genarch/fb/fb.h>
#include <console/chardev.h>
39,159 → 41,125
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <mm/slab.h>
#include <align.h>
#include <panic.h>
#include <memstr.h>
#include <config.h>
#include <bitops.h>
#include <print.h>
#include <string.h>
#include <ddi/ddi.h>
#include <arch/types.h>
 
#include "helenos.xbm"
SPINLOCK_INITIALIZE(fb_lock);
 
static parea_t fb_parea; /**< Physical memory area for fb. */
static uint8_t *fb_addr;
static uint16_t *backbuf;
static uint8_t *glyphs;
static uint8_t *bgscan;
 
SPINLOCK_INITIALIZE(fb_lock);
static unsigned int xres;
static unsigned int yres;
 
static uint8_t *fbaddress = NULL;
static unsigned int ylogo;
static unsigned int ytrim;
static unsigned int rowtrim;
 
static uint8_t *blankline = NULL;
static uint8_t *dbbuffer = NULL; /* Buffer for fast scrolling console */
static index_t dboffset;
static unsigned int scanline;
static unsigned int glyphscanline;
 
static unsigned int xres = 0;
static unsigned int yres = 0;
static unsigned int scanline = 0;
static unsigned int pixelbytes = 0;
#ifdef FB_INVERT_COLORS
static bool invert_colors = true;
#else
static bool invert_colors = false;
#endif
static unsigned int pixelbytes;
static unsigned int glyphbytes;
static unsigned int bgscanbytes;
 
static unsigned int cols;
static unsigned int rows;
static unsigned int position = 0;
static unsigned int columns = 0;
static unsigned int rows = 0;
 
#define COL_WIDTH 8
#define ROW_BYTES (scanline * FONT_SCANLINES)
#define BG_COLOR 0x000080
#define FG_COLOR 0xffff00
#define INV_COLOR 0xaaaaaa
 
#define BGCOLOR 0x000080
#define FGCOLOR 0xffff00
#define LOGOCOLOR 0x2020b0
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1))
 
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1))
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1))
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1))
#define COL2X(col) ((col) * FONT_WIDTH)
#define ROW2Y(row) ((row) * FONT_SCANLINES)
 
#define POINTPOS(x, y) ((y) * scanline + (x) * pixelbytes)
#define X2COL(x) ((x) / FONT_WIDTH)
#define Y2ROW(y) ((y) / FONT_SCANLINES)
 
/***************************************************************/
/* Pixel specific fuctions */
#define FB_POS(x, y) ((y) * scanline + (x) * pixelbytes)
#define BB_POS(col, row) ((row) * cols + (col))
#define GLYPH_POS(glyph, y) ((glyph) * glyphbytes + (y) * glyphscanline)
 
static void (*rgb2scr)(void *, int);
static int (*scr2rgb)(void *);
 
static inline int COLOR(int color)
{
return invert_colors ? ~color : color;
}
static void (*rgb_conv)(void *, uint32_t);
 
/* Conversion routines between different color representations */
static void rgb_byte0888(void *dst, int rgb)
{
*((int *) dst) = rgb;
}
 
static int byte0888_rgb(void *src)
/** ARGB 8:8:8:8 conversion
*
*/
static void rgb_0888(void *dst, uint32_t rgb)
{
return (*((int *) src)) & 0xffffff;
*((uint32_t *) dst) = rgb & 0xffffff;
}
 
static void bgr_byte0888(void *dst, int rgb)
{
*((uint32_t *) dst) = BLUE(rgb, 8) << 16 | GREEN(rgb, 8) << 8 |
RED(rgb, 8);
}
 
static int byte0888_bgr(void *src)
/** ABGR 8:8:8:8 conversion
*
*/
static void bgr_0888(void *dst, uint32_t rgb)
{
int color = *(uint32_t *)(src);
return ((color & 0xff) << 16) | (((color >> 8) & 0xff) << 8) |
((color >> 16) & 0xff);
*((uint32_t *) dst)
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8);
}
 
static void rgb_byte888(void *dst, int rgb)
{
uint8_t *scr = (uint8_t *) dst;
#if defined(FB_INVERT_ENDIAN)
scr[0] = RED(rgb, 8);
scr[1] = GREEN(rgb, 8);
scr[2] = BLUE(rgb, 8);
#else
scr[2] = RED(rgb, 8);
scr[1] = GREEN(rgb, 8);
scr[0] = BLUE(rgb, 8);
#endif
}
 
static int byte888_rgb(void *src)
/** RGB 8:8:8 conversion
*
*/
static void rgb_888(void *dst, uint32_t rgb)
{
uint8_t *scr = (uint8_t *) src;
#if defined(FB_INVERT_ENDIAN)
return scr[0] << 16 | scr[1] << 8 | scr[2];
#else
return scr[2] << 16 | scr[1] << 8 | scr[0];
#endif
((uint8_t *) dst)[0] = BLUE(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = RED(rgb, 8);
}
 
static void bgr_byte8880(void *dst, int rgb)
{
uint8_t *scr = (uint8_t *) dst;
scr[3] = RED(rgb, 8);
scr[2] = GREEN(rgb, 8);
scr[1] = BLUE(rgb, 8);
}
 
static int byte8880_bgr(void *src)
/** BGR 8:8:8 conversion
*
*/
static void bgr_888(void *dst, uint32_t rgb)
{
uint8_t *scr = (uint8_t *) src;
return scr[3] << 16 | scr[2] << 8 | scr[1];
((uint8_t *) dst)[0] = RED(rgb, 8);
((uint8_t *) dst)[1] = GREEN(rgb, 8);
((uint8_t *) dst)[2] = BLUE(rgb, 8);
}
 
/** 16-bit depth (5:5:5) */
static void rgb_byte555(void *dst, int rgb)
{
/* 5-bit, 5-bits, 5-bits */
*((uint16_t *) dst) = RED(rgb, 5) << 10 | GREEN(rgb, 5) << 5 |
BLUE(rgb, 5);
}
 
/** 16-bit depth (5:5:5) */
static int byte555_rgb(void *src)
/** RGB 5:5:5 conversion
*
*/
static void rgb_555(void *dst, uint32_t rgb)
{
int color = *(uint16_t *)(src);
return (((color >> 10) & 0x1f) << (16 + 3)) |
(((color >> 5) & 0x1f) << (8 + 3)) | ((color & 0x1f) << 3);
*((uint16_t *) dst)
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5);
}
 
/** 16-bit depth (5:6:5) */
static void rgb_byte565(void *dst, int rgb)
{
/* 5-bit, 6-bits, 5-bits */
*((uint16_t *) dst) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 |
BLUE(rgb, 5);
}
 
/** 16-bit depth (5:6:5) */
static int byte565_rgb(void *src)
/** RGB 5:6:5 conversion
*
*/
static void rgb_565(void *dst, uint32_t rgb)
{
int color = *(uint16_t *)(src);
return (((color >> 11) & 0x1f) << (16 + 3)) |
(((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3);
*((uint16_t *) dst)
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5);
}
 
/** Put pixel - 8-bit depth (color palette/3:2:3)
 
/** RGB 3:2:3
*
* Even though we try 3:2:3 color scheme here, an 8-bit framebuffer
* will most likely use a color palette. The color appearance
198,258 → 166,279
* will be pretty random and depend on the default installed
* palette. This could be fixed by supporting custom palette
* and setting it to simulate the 8-bit truecolor.
*
* Currently we set the palette on the ia32, amd64 and sparc64 port.
*
* Note that the byte is being inverted by this function. The reason is
* that we would like to use a color palette where the white color code
* is 0 and the black color code is 255, as some machines (Sun Blade 1500)
* use these codes for black and white and prevent to set codes
* 0 and 255 to other colors.
*
*/
static void rgb_byte8(void *dst, int rgb)
static void rgb_323(void *dst, uint32_t rgb)
{
*((uint8_t *) dst) = RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 |
BLUE(rgb, 3);
*((uint8_t *) dst)
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3));
}
 
/** Return pixel color - 8-bit depth (color palette/3:2:3)
 
/** Hide logo and refresh screen
*
* See the comment for rgb_byte().
*/
static int byte8_rgb(void *src)
static void logo_hide(bool silent)
{
int color = *(uint8_t *)src;
return (((color >> 5) & 0x7) << (16 + 5)) |
(((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5);
ylogo = 0;
ytrim = yres;
rowtrim = rows;
if (!silent)
fb_redraw();
}
 
static void putpixel(unsigned int x, unsigned int y, int color)
{
(*rgb2scr)(&fbaddress[POINTPOS(x, y)], COLOR(color));
 
if (dbbuffer) {
int dline = (y + dboffset) % yres;
(*rgb2scr)(&dbbuffer[POINTPOS(x, dline)], COLOR(color));
}
}
 
/** Get pixel from viewport */
static int getpixel(unsigned int x, unsigned int y)
/** Draw character at given position
*
*/
static void glyph_draw(uint16_t glyph, unsigned int col, unsigned int row, bool silent, bool overlay)
{
if (dbbuffer) {
int dline = (y + dboffset) % yres;
return COLOR((*scr2rgb)(&dbbuffer[POINTPOS(x, dline)]));
unsigned int x = COL2X(col);
unsigned int y = ROW2Y(row);
unsigned int yd;
if (y >= ytrim)
logo_hide(silent);
if (!overlay)
backbuf[BB_POS(col, row)] = glyph;
if (!silent) {
for (yd = 0; yd < FONT_SCANLINES; yd++)
memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)],
&glyphs[GLYPH_POS(glyph, yd)], glyphscanline);
}
return COLOR((*scr2rgb)(&fbaddress[POINTPOS(x, y)]));
}
 
 
/** Fill screen with background color */
static void clear_screen(void)
/** Scroll screen down by one row
*
*
*/
static void screen_scroll(bool silent)
{
unsigned int y;
 
for (y = 0; y < yres; y++) {
memcpy(&fbaddress[scanline * y], blankline, xres * pixelbytes);
if (dbbuffer)
memcpy(&dbbuffer[scanline * y], blankline,
xres * pixelbytes);
if (ylogo > 0) {
logo_hide(silent);
return;
}
}
 
 
/** Scroll screen one row up */
static void scroll_screen(void)
{
if (dbbuffer) {
count_t first;
if (!silent) {
unsigned int row;
/* Clear the last row */
memcpy(&dbbuffer[dboffset * scanline], blankline, ROW_BYTES);
dboffset = (dboffset + FONT_SCANLINES) % yres;
first = yres - dboffset;
/* Move all rows one row up */
if (xres * pixelbytes == scanline) {
memcpy(fbaddress, &dbbuffer[dboffset * scanline],
first * scanline);
memcpy(&fbaddress[first * scanline], dbbuffer,
dboffset * scanline);
} else {
/*
* When the scanline is bigger than number of bytes
* in the X-resolution, chances are that the
* frame buffer memory past the X-resolution is special
* in some way. For example, the SUNW,ffb framebuffer
* wraps this area around the beginning of the same
* line. To avoid troubles, copy only memory as
* specified by the resolution.
*/
unsigned int i;
 
for (i = 0; i < first; i++)
memcpy(&fbaddress[i * scanline],
&dbbuffer[(dboffset + i) * scanline],
xres * pixelbytes);
for (i = 0; i < dboffset; i++)
memcpy(&fbaddress[(first + i) * scanline],
&dbbuffer[i * scanline], xres * pixelbytes);
for (row = 0; row < rows; row++) {
unsigned int y = ROW2Y(row);
unsigned int yd;
for (yd = 0; yd < FONT_SCANLINES; yd++) {
unsigned int x;
unsigned int col;
for (col = 0, x = 0; col < cols; col++,
x += FONT_WIDTH) {
uint16_t glyph;
if (row < rows - 1) {
if (backbuf[BB_POS(col, row)] ==
backbuf[BB_POS(col, row + 1)])
continue;
glyph = backbuf[BB_POS(col, row + 1)];
} else
glyph = 0;
memcpy(&fb_addr[FB_POS(x, y + yd)],
&glyphs[GLYPH_POS(glyph, yd)],
glyphscanline);
}
}
}
} else {
uint8_t *lastline = &fbaddress[(rows - 1) * ROW_BYTES];
if (xres * pixelbytes == scanline) {
/* Move all rows one row up */
memcpy((void *) fbaddress,
(void *) &fbaddress[ROW_BYTES],
scanline * yres - ROW_BYTES);
/* Clear the last row */
memcpy((void *) lastline, (void *) blankline,
ROW_BYTES);
} else {
/*
* See the comment in the dbbuffer case.
*/
unsigned int i;
 
/* Move all rows one row up */
for (i = 0; i < yres - FONT_SCANLINES; i++)
memcpy(&fbaddress[i * scanline],
&fbaddress[(i + FONT_SCANLINES) * scanline],
xres * pixelbytes);
/* Clear the last row */
for (i = 0; i < FONT_SCANLINES; i++)
memcpy(&lastline[i * scanline],
&blankline[i * scanline],
xres * pixelbytes);
}
}
memmove(backbuf, &backbuf[BB_POS(0, 1)], cols * (rows - 1) * sizeof(uint16_t));
memsetw(&backbuf[BB_POS(0, rows - 1)], cols, 0);
}
 
 
static void invert_pixel(unsigned int x, unsigned int y)
static void cursor_put(bool silent)
{
putpixel(x, y, ~getpixel(x, y));
unsigned int col = position % cols;
unsigned int row = position / cols;
glyph_draw(fb_font_glyph(U_CURSOR), col, row, silent, true);
}
 
 
/** Draw one line of glyph at a given position */
static void draw_glyph_line(unsigned int glline, unsigned int x, unsigned int y)
static void cursor_remove(bool silent)
{
unsigned int i;
 
for (i = 0; i < 8; i++)
if (glline & (1 << (7 - i))) {
putpixel(x + i, y, FGCOLOR);
} else
putpixel(x + i, y, BGCOLOR);
unsigned int col = position % cols;
unsigned int row = position / cols;
glyph_draw(backbuf[BB_POS(col, row)], col, row, silent, true);
}
 
/***************************************************************/
/* Character-console functions */
 
/** Draw character at given position */
static void draw_glyph(uint8_t glyph, unsigned int col, unsigned int row)
{
unsigned int y;
 
for (y = 0; y < FONT_SCANLINES; y++)
draw_glyph_line(fb_font[glyph * FONT_SCANLINES + y],
col * COL_WIDTH, row * FONT_SCANLINES + y);
}
 
/** Invert character at given position */
static void invert_char(unsigned int col, unsigned int row)
{
unsigned int x;
unsigned int y;
 
for (x = 0; x < COL_WIDTH; x++)
for (y = 0; y < FONT_SCANLINES; y++)
invert_pixel(col * COL_WIDTH + x,
row * FONT_SCANLINES + y);
}
 
/** Draw character at default position */
static void draw_char(char chr)
{
draw_glyph(chr, position % columns, position / columns);
}
 
static void draw_logo(unsigned int startx, unsigned int starty)
{
unsigned int x;
unsigned int y;
unsigned int byte;
unsigned int rowbytes;
 
rowbytes = (helenos_width - 1) / 8 + 1;
 
for (y = 0; y < helenos_height; y++)
for (x = 0; x < helenos_width; x++) {
byte = helenos_bits[rowbytes * y + x / 8];
byte >>= x % 8;
if (byte & 1)
putpixel(startx + x, starty + y,
COLOR(LOGOCOLOR));
}
}
 
/***************************************************************/
/* Stdout specific functions */
 
static void invert_cursor(void)
{
invert_char(position % columns, position / columns);
}
 
/** Print character to screen
*
* Emulate basic terminal commands
* Emulate basic terminal commands.
*
*/
static void fb_putchar(chardev_t *dev, char ch)
static void fb_putchar(outdev_t *dev, wchar_t ch, bool silent)
{
spinlock_lock(&fb_lock);
switch (ch) {
case '\n':
invert_cursor();
position += columns;
position -= position % columns;
cursor_remove(silent);
position += cols;
position -= position % cols;
break;
case '\r':
invert_cursor();
position -= position % columns;
cursor_remove(silent);
position -= position % cols;
break;
case '\b':
invert_cursor();
if (position % columns)
cursor_remove(silent);
if (position % cols)
position--;
break;
case '\t':
invert_cursor();
cursor_remove(silent);
do {
draw_char(' ');
glyph_draw(fb_font_glyph(' '), position % cols,
position / cols, silent, false);
position++;
} while ((position % 8) && position < columns * rows);
} while ((position % 8) && (position < cols * rows));
break;
default:
draw_char(ch);
glyph_draw(fb_font_glyph(ch), position % cols,
position / cols, silent, false);
position++;
}
if (position >= columns * rows) {
position -= columns;
scroll_screen();
if (position >= cols * rows) {
position -= cols;
screen_scroll(silent);
}
invert_cursor();
cursor_put(silent);
spinlock_unlock(&fb_lock);
}
 
static chardev_t framebuffer;
static chardev_operations_t fb_ops = {
.write = fb_putchar,
static outdev_t fb_console;
static outdev_operations_t fb_ops = {
.write = fb_putchar
};
 
 
/** Initialize framebuffer as a chardev output device
/** Render glyphs
*
* Convert glyphs from device independent font
* description to current visual representation.
*
*/
static void glyphs_render(void)
{
/* Prerender glyphs */
uint16_t glyph;
for (glyph = 0; glyph < FONT_GLYPHS; glyph++) {
uint32_t fg_color;
if (glyph == FONT_GLYPHS - 1)
fg_color = INV_COLOR;
else
fg_color = FG_COLOR;
unsigned int y;
for (y = 0; y < FONT_SCANLINES; y++) {
unsigned int x;
for (x = 0; x < FONT_WIDTH; x++) {
void *dst = &glyphs[GLYPH_POS(glyph, y) +
x * pixelbytes];
uint32_t rgb = (fb_font[glyph][y] &
(1 << (7 - x))) ? fg_color : BG_COLOR;
rgb_conv(dst, rgb);
}
}
}
/* Prerender background scanline */
unsigned int x;
for (x = 0; x < xres; x++)
rgb_conv(&bgscan[x * pixelbytes], BG_COLOR);
}
 
 
/** Refresh the screen
*
*/
void fb_redraw(void)
{
if (ylogo > 0) {
unsigned int y;
for (y = 0; y < LOGO_HEIGHT; y++) {
unsigned int x;
for (x = 0; x < xres; x++)
rgb_conv(&fb_addr[FB_POS(x, y)],
(x < LOGO_WIDTH) ?
fb_logo[y * LOGO_WIDTH + x] :
LOGO_COLOR);
}
}
unsigned int row;
for (row = 0; row < rowtrim; row++) {
unsigned int y = ylogo + ROW2Y(row);
unsigned int yd;
for (yd = 0; yd < FONT_SCANLINES; yd++) {
unsigned int x;
unsigned int col;
for (col = 0, x = 0; col < cols;
col++, x += FONT_WIDTH) {
uint16_t glyph = backbuf[BB_POS(col, row)];
void *dst = &fb_addr[FB_POS(x, y + yd)];
void *src = &glyphs[GLYPH_POS(glyph, yd)];
memcpy(dst, src, glyphscanline);
}
}
}
if (COL2X(cols) < xres) {
unsigned int y;
unsigned int size = (xres - COL2X(cols)) * pixelbytes;
for (y = ylogo; y < yres; y++)
memcpy(&fb_addr[FB_POS(COL2X(cols), y)], bgscan, size);
}
if (ROW2Y(rowtrim) + ylogo < yres) {
unsigned int y;
for (y = ROW2Y(rowtrim) + ylogo; y < yres; y++)
memcpy(&fb_addr[FB_POS(0, y)], bgscan, bgscanbytes);
}
}
 
 
/** Initialize framebuffer as a output character device
*
* @param addr Physical address of the framebuffer
* @param x Screen width in pixels
* @param y Screen height in pixels
457,106 → 446,102
* @param visual Color model
*
*/
void fb_init(uintptr_t addr, unsigned int x, unsigned int y, unsigned int scan,
unsigned int visual)
void fb_init(fb_properties_t *props)
{
switch (visual) {
switch (props->visual) {
case VISUAL_INDIRECT_8:
rgb2scr = rgb_byte8;
scr2rgb = byte8_rgb;
rgb_conv = rgb_323;
pixelbytes = 1;
break;
case VISUAL_RGB_5_5_5:
rgb2scr = rgb_byte555;
scr2rgb = byte555_rgb;
rgb_conv = rgb_555;
pixelbytes = 2;
break;
case VISUAL_RGB_5_6_5:
rgb2scr = rgb_byte565;
scr2rgb = byte565_rgb;
rgb_conv = rgb_565;
pixelbytes = 2;
break;
case VISUAL_RGB_8_8_8:
rgb2scr = rgb_byte888;
scr2rgb = byte888_rgb;
rgb_conv = rgb_888;
pixelbytes = 3;
break;
case VISUAL_BGR_8_8_8:
rgb_conv = bgr_888;
pixelbytes = 3;
break;
case VISUAL_RGB_8_8_8_0:
rgb2scr = rgb_byte888;
scr2rgb = byte888_rgb;
rgb_conv = rgb_888;
pixelbytes = 4;
break;
case VISUAL_RGB_0_8_8_8:
rgb2scr = rgb_byte0888;
scr2rgb = byte0888_rgb;
rgb_conv = rgb_0888;
pixelbytes = 4;
break;
case VISUAL_BGR_0_8_8_8:
rgb2scr = bgr_byte0888;
scr2rgb = byte0888_bgr;
rgb_conv = bgr_0888;
pixelbytes = 4;
break;
case VISUAL_BGR_8_8_8_0:
rgb2scr = bgr_byte8880;
scr2rgb = byte8880_bgr;
pixelbytes = 4;
break;
default:
panic("Unsupported visual.\n");
panic("Unsupported visual.");
}
unsigned int fbsize = scan * y;
xres = props->x;
yres = props->y;
scanline = props->scan;
/* Map the framebuffer */
fbaddress = (uint8_t *) hw_map((uintptr_t) addr, fbsize);
cols = X2COL(xres);
rows = Y2ROW(yres);
xres = x;
yres = y;
scanline = scan;
if (yres > ylogo) {
ylogo = LOGO_HEIGHT;
rowtrim = rows - Y2ROW(ylogo);
if (ylogo % FONT_SCANLINES > 0)
rowtrim--;
ytrim = ROW2Y(rowtrim);
} else {
ylogo = 0;
ytrim = yres;
rowtrim = rows;
}
rows = y / FONT_SCANLINES;
columns = x / COL_WIDTH;
 
fb_parea.pbase = (uintptr_t) addr;
fb_parea.vbase = (uintptr_t) fbaddress;
fb_parea.frames = SIZE2FRAMES(fbsize);
fb_parea.cacheable = false;
ddi_parea_register(&fb_parea);
 
glyphscanline = FONT_WIDTH * pixelbytes;
glyphbytes = ROW2Y(glyphscanline);
bgscanbytes = xres * pixelbytes;
size_t fbsize = scanline * yres;
size_t bbsize = cols * rows * sizeof(uint16_t);
size_t glyphsize = FONT_GLYPHS * glyphbytes;
backbuf = (uint16_t *) malloc(bbsize, 0);
if (!backbuf)
panic("Unable to allocate backbuffer.");
glyphs = (uint8_t *) malloc(glyphsize, 0);
if (!glyphs)
panic("Unable to allocate glyphs.");
bgscan = malloc(bgscanbytes, 0);
if (!bgscan)
panic("Unable to allocate background pixel.");
memsetw(backbuf, cols * rows, 0);
glyphs_render();
fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 1);
sysinfo_set_item_val("fb.width", NULL, xres);
sysinfo_set_item_val("fb.height", NULL, yres);
sysinfo_set_item_val("fb.scanline", NULL, scan);
sysinfo_set_item_val("fb.visual", NULL, visual);
sysinfo_set_item_val("fb.address.physical", NULL, addr);
sysinfo_set_item_val("fb.invert-colors", NULL, invert_colors);
 
/* Allocate double buffer */
unsigned int order = fnzb(SIZE2FRAMES(fbsize) - 1) + 1;
dbbuffer = (uint8_t *) frame_alloc(order, FRAME_ATOMIC | FRAME_KA);
if (!dbbuffer)
printf("Failed to allocate scroll buffer.\n");
dboffset = 0;
 
/* Initialized blank line */
blankline = (uint8_t *) malloc(ROW_BYTES, FRAME_ATOMIC);
if (!blankline)
panic("Failed to allocate blank line for framebuffer.");
for (y = 0; y < FONT_SCANLINES; y++)
for (x = 0; x < xres; x++)
(*rgb2scr)(&blankline[POINTPOS(x, y)], COLOR(BGCOLOR));
sysinfo_set_item_val("fb.scanline", NULL, scanline);
sysinfo_set_item_val("fb.visual", NULL, props->visual);
sysinfo_set_item_val("fb.address.physical", NULL, props->addr);
clear_screen();
 
/* Update size of screen to match text area */
yres = rows * FONT_SCANLINES;
 
draw_logo(xres - helenos_width, 0);
invert_cursor();
 
chardev_initialize("fb", &framebuffer, &fb_ops);
stdout = &framebuffer;
fb_redraw();
outdev_initialize("fb", &fb_console, &fb_ops);
stdout = &fb_console;
}
 
/** @}
/branches/arm/kernel/genarch/src/fb/font-8x16.c
1,5 → 1,6
/*
* Copyright (c) 2005 Martin Decky
* Copyright (c) 2000 Dmitry Bolkhovityanov
* Copyright (c) 2009 Martin Decky
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
26,7 → 27,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup genarch
/** @addtogroup genarch
* @{
*/
/** @file
34,4616 → 35,3235
 
#include <genarch/fb/font-8x16.h>
 
unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES] = {
/** Convert character to font glyph index
*
* The font does not cover all Unicode characters.
* This function converts the character to an appropriate
* glyph in the font or returns an index to the question
* mark glyph if no specific glyph exists.
*/
uint16_t fb_font_glyph(const wchar_t ch)
{
if (ch == 0x0000)
return 0;
if ((ch >= 0x0020) && (ch <= 0x007f))
return (ch - 32);
if ((ch >= 0x00a0) && (ch <= 0x021f))
return (ch - 64);
if ((ch >= 0x0222) && (ch <= 0x0233))
return (ch - 66);
if ((ch >= 0x0250) && (ch <= 0x02ad))
return (ch - 94);
if ((ch >= 0x02b0) && (ch <= 0x02cf))
return (ch - 96);
if ((ch >= 0x02d8) && (ch <= 0x02dd))
return (ch - 104);
if (ch == 0x02ee)
return 630;
if ((ch >= 0x0300) && (ch <= 0x0301))
return (ch - 137);
if (ch == 0x0303)
return 633;
if (ch == 0x0309)
return 634;
if ((ch >= 0x0312) && (ch <= 0x0314))
return (ch - 151);
if (ch == 0x0323)
return 638;
if ((ch >= 0x0340) && (ch <= 0x0341))
return (ch - 193);
if ((ch >= 0x0374) && (ch <= 0x0375))
return (ch - 243);
if (ch == 0x037a)
return 643;
if (ch == 0x037e)
return 644;
if ((ch >= 0x0384) && (ch <= 0x038a))
return (ch - 255);
if (ch == 0x038c)
return 652;
if ((ch >= 0x038e) && (ch <= 0x03a1))
return (ch - 257);
if ((ch >= 0x03a3) && (ch <= 0x03ce))
return (ch - 258);
if ((ch >= 0x03d0) && (ch <= 0x03d7))
return (ch - 259);
if ((ch >= 0x03da) && (ch <= 0x03f3))
return (ch - 261);
if ((ch >= 0x0400) && (ch <= 0x0486))
return (ch - 273);
if ((ch >= 0x0488) && (ch <= 0x04ce))
return (ch - 274);
if ((ch >= 0x04d0) && (ch <= 0x04f5))
return (ch - 275);
if ((ch >= 0x04f8) && (ch <= 0x04f9))
return (ch - 277);
if ((ch >= 0x0500) && (ch <= 0x050f))
return (ch - 283);
if ((ch >= 0x0530) && (ch <= 0x0556))
return (ch - 315);
if ((ch >= 0x0559) && (ch <= 0x055f))
return (ch - 317);
if ((ch >= 0x0561) && (ch <= 0x0587))
return (ch - 318);
if ((ch >= 0x0589) && (ch <= 0x058a))
return (ch - 319);
if ((ch >= 0x0591) && (ch <= 0x05a1))
return (ch - 325);
if ((ch >= 0x05a3) && (ch <= 0x05b9))
return (ch - 326);
if ((ch >= 0x05bb) && (ch <= 0x05c4))
return (ch - 327);
if ((ch >= 0x05d0) && (ch <= 0x05ea))
return (ch - 338);
if ((ch >= 0x05f0) && (ch <= 0x05f4))
return (ch - 343);
if (ch == 0x060c)
return 1182;
if (ch == 0x061b)
return 1183;
if (ch == 0x061f)
return 1184;
if ((ch >= 0x0621) && (ch <= 0x063a))
return (ch - 384);
if ((ch >= 0x0640) && (ch <= 0x0655))
return (ch - 389);
if ((ch >= 0x0660) && (ch <= 0x066d))
return (ch - 399);
if ((ch >= 0x0670) && (ch <= 0x06ed))
return (ch - 401);
if ((ch >= 0x06f0) && (ch <= 0x06fe))
return (ch - 403);
if (ch == 0x10d3)
return 1388;
if (ch == 0x10d7)
return 1389;
if (ch == 0x10da)
return 1390;
if (ch == 0x10dd)
return 1391;
if (ch == 0x10e6)
return 1392;
if ((ch >= 0x1e00) && (ch <= 0x1e9b))
return (ch - 6287);
if ((ch >= 0x1ea0) && (ch <= 0x1ef9))
return (ch - 6291);
if ((ch >= 0x1f00) && (ch <= 0x1f07))
return (ch - 6297);
if ((ch >= 0x2000) && (ch <= 0x2027))
return (ch - 6545);
if ((ch >= 0x2030) && (ch <= 0x2046))
return (ch - 6553);
if ((ch >= 0x2048) && (ch <= 0x204d))
return (ch - 6554);
if (ch == 0x2070)
return 1716;
if ((ch >= 0x2074) && (ch <= 0x208f))
return (ch - 6591);
if ((ch >= 0x20a0) && (ch <= 0x20af))
return (ch - 6607);
if ((ch >= 0x2100) && (ch <= 0x213a))
return (ch - 6687);
if ((ch >= 0x2153) && (ch <= 0x2183))
return (ch - 6711);
if ((ch >= 0x2190) && (ch <= 0x21f3))
return (ch - 6723);
if ((ch >= 0x2200) && (ch <= 0x22f1))
return (ch - 6735);
if (ch == 0x2300)
return 2211;
if (ch == 0x2302)
return 2212;
if ((ch >= 0x2308) && (ch <= 0x230b))
return (ch - 6755);
if (ch == 0x2310)
return 2217;
if (ch == 0x2318)
return 2218;
if ((ch >= 0x231a) && (ch <= 0x231b))
return (ch - 6767);
if ((ch >= 0x2320) && (ch <= 0x2321))
return (ch - 6771);
if ((ch >= 0x2329) && (ch <= 0x232a))
return (ch - 6778);
if ((ch >= 0x239b) && (ch <= 0x23bd))
return (ch - 6890);
if (ch == 0x23ce)
return 2260;
if ((ch >= 0x2409) && (ch <= 0x240d))
return (ch - 6964);
if ((ch >= 0x2423) && (ch <= 0x2424))
return (ch - 6985);
if (ch == 0x2426)
return 2268;
if ((ch >= 0x2500) && (ch <= 0x2595))
return (ch - 7203);
if ((ch >= 0x25a0) && (ch <= 0x25f7))
return (ch - 7213);
if ((ch >= 0x2600) && (ch <= 0x2602))
return (ch - 7221);
if ((ch >= 0x2605) && (ch <= 0x260d))
return (ch - 7223);
if ((ch >= 0x2610) && (ch <= 0x2613))
return (ch - 7225);
if (ch == 0x2620)
return 2523;
if (ch == 0x2622)
return 2524;
if (ch == 0x2626)
return 2525;
if ((ch >= 0x2628) && (ch <= 0x262b))
return (ch - 7242);
if ((ch >= 0x262e) && (ch <= 0x2637))
return (ch - 7244);
if ((ch >= 0x2639) && (ch <= 0x2653))
return (ch - 7245);
if ((ch >= 0x2660) && (ch <= 0x2667))
return (ch - 7257);
if ((ch >= 0x2669) && (ch <= 0x266f))
return (ch - 7258);
if ((ch >= 0xfb00) && (ch <= 0xfb05))
return (ch - 61674);
if ((ch >= 0xfb50) && (ch <= 0xfbb1))
return (ch - 61748);
if ((ch >= 0xfbd3) && (ch <= 0xfbe9))
return (ch - 61781);
if ((ch >= 0xfbfc) && (ch <= 0xfbff))
return (ch - 61799);
if ((ch >= 0xfc5b) && (ch <= 0xfc63))
return (ch - 61890);
if (ch == 0xfc90)
return 2722;
if ((ch >= 0xfcf2) && (ch <= 0xfcf4))
return (ch - 62031);
if ((ch >= 0xfd3c) && (ch <= 0xfd3f))
return (ch - 62102);
if (ch == 0xfdf2)
return 2730;
if ((ch >= 0xfe50) && (ch <= 0xfe52))
return (ch - 62373);
if ((ch >= 0xfe54) && (ch <= 0xfe66))
return (ch - 62374);
if ((ch >= 0xfe68) && (ch <= 0xfe6b))
return (ch - 62375);
if ((ch >= 0xfe70) && (ch <= 0xfe72))
return (ch - 62379);
if (ch == 0xfe74)
return 2760;
if ((ch >= 0xfe76) && (ch <= 0xfefc))
return (ch - 62381);
if (ch == 0xfeff)
return 2896;
return 2898;
}
 
/* 0 0x00 '^@' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 1 0x01 '^A' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x81, /* 10000001 */
0xa5, /* 10100101 */
0x81, /* 10000001 */
0x81, /* 10000001 */
0xbd, /* 10111101 */
0x99, /* 10011001 */
0x81, /* 10000001 */
0x81, /* 10000001 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 2 0x02 '^B' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xff, /* 11111111 */
0xdb, /* 11011011 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xc3, /* 11000011 */
0xe7, /* 11100111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 3 0x03 '^C' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 4 0x04 '^D' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 5 0x05 '^E' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0xe7, /* 11100111 */
0xe7, /* 11100111 */
0xe7, /* 11100111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 6 0x06 '^F' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 7 0x07 '^G' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 8 0x08 '^H' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xe7, /* 11100111 */
0xc3, /* 11000011 */
0xc3, /* 11000011 */
0xe7, /* 11100111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 9 0x09 '^I' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x42, /* 01000010 */
0x42, /* 01000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 10 0x0a '^J' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xc3, /* 11000011 */
0x99, /* 10011001 */
0xbd, /* 10111101 */
0xbd, /* 10111101 */
0x99, /* 10011001 */
0xc3, /* 11000011 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 11 0x0b '^K' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x0e, /* 00001110 */
0x1a, /* 00011010 */
0x32, /* 00110010 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 12 0x0c '^L' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 13 0x0d '^M' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x33, /* 00110011 */
0x3f, /* 00111111 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x70, /* 01110000 */
0xf0, /* 11110000 */
0xe0, /* 11100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 14 0x0e '^N' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7f, /* 01111111 */
0x63, /* 01100011 */
0x7f, /* 01111111 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x63, /* 01100011 */
0x67, /* 01100111 */
0xe7, /* 11100111 */
0xe6, /* 11100110 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 15 0x0f '^O' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xdb, /* 11011011 */
0x3c, /* 00111100 */
0xe7, /* 11100111 */
0x3c, /* 00111100 */
0xdb, /* 11011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 16 0x10 '^P' */
0x00, /* 00000000 */
0x80, /* 10000000 */
0xc0, /* 11000000 */
0xe0, /* 11100000 */
0xf0, /* 11110000 */
0xf8, /* 11111000 */
0xfe, /* 11111110 */
0xf8, /* 11111000 */
0xf0, /* 11110000 */
0xe0, /* 11100000 */
0xc0, /* 11000000 */
0x80, /* 10000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 17 0x11 '^Q' */
0x00, /* 00000000 */
0x02, /* 00000010 */
0x06, /* 00000110 */
0x0e, /* 00001110 */
0x1e, /* 00011110 */
0x3e, /* 00111110 */
0xfe, /* 11111110 */
0x3e, /* 00111110 */
0x1e, /* 00011110 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x02, /* 00000010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 18 0x12 '^R' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 19 0x13 '^S' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 20 0x14 '^T' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7f, /* 01111111 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0x7b, /* 01111011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 21 0x15 '^U' */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 22 0x16 '^V' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 23 0x17 '^W' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 24 0x18 '^X' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 25 0x19 '^Y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 26 0x1a '^Z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0xfe, /* 11111110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 27 0x1b '^[' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xfe, /* 11111110 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 28 0x1c '^\' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 29 0x1d '^]' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x28, /* 00101000 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x28, /* 00101000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 30 0x1e '^^' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0x7c, /* 01111100 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 31 0x1f '^_' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0x7c, /* 01111100 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 32 0x20 ' ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 33 0x21 '!' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 34 0x22 '"' */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x24, /* 00100100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 35 0x23 '#' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 36 0x24 '$' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0x7c, /* 01111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x86, /* 10000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 37 0x25 '%' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc2, /* 11000010 */
0xc6, /* 11000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0x86, /* 10000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 38 0x26 '&' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 39 0x27 ''' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 40 0x28 '(' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 41 0x29 ')' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 42 0x2a '*' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0xff, /* 11111111 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 43 0x2b '+' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 44 0x2c ',' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 45 0x2d '-' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 46 0x2e '.' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 47 0x2f '/' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x02, /* 00000010 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x80, /* 10000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 48 0x30 '0' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 49 0x31 '1' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x38, /* 00111000 */
0x78, /* 01111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 50 0x32 '2' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 51 0x33 '3' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x3c, /* 00111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 52 0x34 '4' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x1c, /* 00011100 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xfe, /* 11111110 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x1e, /* 00011110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 53 0x35 '5' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfc, /* 11111100 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 54 0x36 '6' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xfc, /* 11111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 55 0x37 '7' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 56 0x38 '8' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 57 0x39 '9' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 58 0x3a ':' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 59 0x3b ';' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 60 0x3c '<' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 61 0x3d '=' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 62 0x3e '>' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 63 0x3f '?' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 64 0x40 '@' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xde, /* 11011110 */
0xde, /* 11011110 */
0xde, /* 11011110 */
0xdc, /* 11011100 */
0xc0, /* 11000000 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 65 0x41 'A' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 66 0x42 'B' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xfc, /* 11111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 67 0x43 'C' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc2, /* 11000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 68 0x44 'D' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 69 0x45 'E' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x60, /* 01100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 70 0x46 'F' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 71 0x47 'G' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xde, /* 11011110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x66, /* 01100110 */
0x3a, /* 00111010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 72 0x48 'H' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 73 0x49 'I' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 74 0x4a 'J' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 75 0x4b 'K' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe6, /* 11100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x78, /* 01111000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 76 0x4c 'L' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf0, /* 11110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 77 0x4d 'M' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xee, /* 11101110 */
0xfe, /* 11111110 */
0xfe, /* 11111110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 78 0x4e 'N' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xe6, /* 11100110 */
0xf6, /* 11110110 */
0xfe, /* 11111110 */
0xde, /* 11011110 */
0xce, /* 11001110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 79 0x4f 'O' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 80 0x50 'P' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 81 0x51 'Q' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xde, /* 11011110 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0x0e, /* 00001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 82 0x52 'R' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfc, /* 11111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 83 0x53 'S' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 84 0x54 'T' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x5a, /* 01011010 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 85 0x55 'U' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 86 0x56 'V' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 87 0x57 'W' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xfe, /* 11111110 */
0xee, /* 11101110 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 88 0x58 'X' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x7c, /* 01111100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x7c, /* 01111100 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 89 0x59 'Y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 90 0x5a 'Z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x86, /* 10000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc2, /* 11000010 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 91 0x5b '[' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 92 0x5c '\' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x80, /* 10000000 */
0xc0, /* 11000000 */
0xe0, /* 11100000 */
0x70, /* 01110000 */
0x38, /* 00111000 */
0x1c, /* 00011100 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x02, /* 00000010 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 93 0x5d ']' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 94 0x5e '^' */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 95 0x5f '_' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 96 0x60 '`' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 97 0x61 'a' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 98 0x62 'b' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 99 0x63 'c' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 100 0x64 'd' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 101 0x65 'e' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 102 0x66 'f' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x36, /* 00110110 */
0x32, /* 00110010 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 103 0x67 'g' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0xcc, /* 11001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
 
/* 104 0x68 'h' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x6c, /* 01101100 */
0x76, /* 01110110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 105 0x69 'i' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 106 0x6a 'j' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
 
/* 107 0x6b 'k' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xe0, /* 11100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x78, /* 01111000 */
0x78, /* 01111000 */
0x6c, /* 01101100 */
0x66, /* 01100110 */
0xe6, /* 11100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 108 0x6c 'l' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 109 0x6d 'm' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xec, /* 11101100 */
0xfe, /* 11111110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 110 0x6e 'n' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 111 0x6f 'o' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 112 0x70 'p' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
 
/* 113 0x71 'q' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x7c, /* 01111100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x1e, /* 00011110 */
0x00, /* 00000000 */
 
/* 114 0x72 'r' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x76, /* 01110110 */
0x66, /* 01100110 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 115 0x73 's' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x38, /* 00111000 */
0x0c, /* 00001100 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 116 0x74 't' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0xfc, /* 11111100 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x36, /* 00110110 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 117 0x75 'u' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 118 0x76 'v' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 119 0x77 'w' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xd6, /* 11010110 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 120 0x78 'x' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 121 0x79 'y' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
 
/* 122 0x7a 'z' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xcc, /* 11001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 123 0x7b '{' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x0e, /* 00001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 124 0x7c '|' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 125 0x7d '}' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x70, /* 01110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x0e, /* 00001110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 126 0x7e '~' */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 127 0x7f '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 128 0x80 '€' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0xc2, /* 11000010 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc2, /* 11000010 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 129 0x81 '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 130 0x82 '‚' */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 131 0x83 'ƒ' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 132 0x84 '„' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 133 0x85 '…' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 134 0x86 '†' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 135 0x87 '‡' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 136 0x88 'ˆ' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 137 0x89 '‰' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 138 0x8a 'Š' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 139 0x8b '‹' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 140 0x8c 'Œ' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 141 0x8d '' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 142 0x8e 'Ž' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 143 0x8f '' */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 144 0x90 '' */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x66, /* 01100110 */
0x62, /* 01100010 */
0x68, /* 01101000 */
0x78, /* 01111000 */
0x68, /* 01101000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 145 0x91 '‘' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xec, /* 11101100 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x7e, /* 01111110 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x6e, /* 01101110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 146 0x92 '’' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3e, /* 00111110 */
0x6c, /* 01101100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xfe, /* 11111110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xce, /* 11001110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 147 0x93 '“' */
0x00, /* 00000000 */
0x10, /* 00010000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 148 0x94 '”' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 149 0x95 '•' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 150 0x96 '–' */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 151 0x97 '—' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 152 0x98 '˜' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7e, /* 01111110 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x78, /* 01111000 */
0x00, /* 00000000 */
 
/* 153 0x99 '™' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 154 0x9a 'š' */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 155 0x9b '›' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 156 0x9c 'œ' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x64, /* 01100100 */
0x60, /* 01100000 */
0xf0, /* 11110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xe6, /* 11100110 */
0xfc, /* 11111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 157 0x9d '' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 158 0x9e 'ž' */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xf8, /* 11111000 */
0xc4, /* 11000100 */
0xcc, /* 11001100 */
0xde, /* 11011110 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 159 0x9f 'Ÿ' */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x1b, /* 00011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 160 0xa0 ' ' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0x0c, /* 00001100 */
0x7c, /* 01111100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 161 0xa1 '¡' */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 162 0xa2 '¢' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 163 0xa3 '£' */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x00, /* 00000000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 164 0xa4 '¤' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0xdc, /* 11011100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 165 0xa5 '¥' */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0xc6, /* 11000110 */
0xe6, /* 11100110 */
0xf6, /* 11110110 */
0xfe, /* 11111110 */
0xde, /* 11011110 */
0xce, /* 11001110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 166 0xa6 '¦' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x3e, /* 00111110 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 167 0xa7 '§' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 168 0xa8 '¨' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x7c, /* 01111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 169 0xa9 '©' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 170 0xaa 'ª' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 171 0xab '«' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0xe0, /* 11100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xdc, /* 11011100 */
0x86, /* 10000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x3e, /* 00111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 172 0xac '¬' */
0x00, /* 00000000 */
0x60, /* 01100000 */
0xe0, /* 11100000 */
0x62, /* 01100010 */
0x66, /* 01100110 */
0x6c, /* 01101100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x66, /* 01100110 */
0xce, /* 11001110 */
0x9a, /* 10011010 */
0x3f, /* 00111111 */
0x06, /* 00000110 */
0x06, /* 00000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 173 0xad '­' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 174 0xae '®' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x36, /* 00110110 */
0x6c, /* 01101100 */
0xd8, /* 11011000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 175 0xaf '¯' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xd8, /* 11011000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x6c, /* 01101100 */
0xd8, /* 11011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 176 0xb0 '°' */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
0x11, /* 00010001 */
0x44, /* 01000100 */
 
/* 177 0xb1 '±' */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
0x55, /* 01010101 */
0xaa, /* 10101010 */
 
/* 178 0xb2 '²' */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
0xdd, /* 11011101 */
0x77, /* 01110111 */
 
/* 179 0xb3 '³' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 180 0xb4 '´' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 181 0xb5 'µ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 182 0xb6 '¶' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 183 0xb7 '·' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 184 0xb8 '¸' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 185 0xb9 '¹' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x06, /* 00000110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 186 0xba 'º' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 187 0xbb '»' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x06, /* 00000110 */
0xf6, /* 11110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 188 0xbc '¼' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf6, /* 11110110 */
0x06, /* 00000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 189 0xbd '½' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 190 0xbe '¾' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 191 0xbf '¿' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xf8, /* 11111000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 192 0xc0 'À' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 193 0xc1 'Á' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 194 0xc2 'Â' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 195 0xc3 'Ã' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 196 0xc4 'Ä' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 197 0xc5 'Å' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 198 0xc6 'Æ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 199 0xc7 'Ç' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 200 0xc8 'È' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x30, /* 00110000 */
0x3f, /* 00111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 201 0xc9 'É' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x30, /* 00110000 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 202 0xca 'Ê' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf7, /* 11110111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 203 0xcb 'Ë' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xf7, /* 11110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 204 0xcc 'Ì' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x37, /* 00110111 */
0x30, /* 00110000 */
0x37, /* 00110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 205 0xcd 'Í' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 206 0xce 'Î' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xf7, /* 11110111 */
0x00, /* 00000000 */
0xf7, /* 11110111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 207 0xcf 'Ï' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 208 0xd0 'Ð' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 209 0xd1 'Ñ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 210 0xd2 'Ò' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 211 0xd3 'Ó' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x3f, /* 00111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 212 0xd4 'Ô' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 213 0xd5 'Õ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 214 0xd6 'Ö' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x3f, /* 00111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 215 0xd7 '×' */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0xff, /* 11111111 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
 
/* 216 0xd8 'Ø' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0xff, /* 11111111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 217 0xd9 'Ù' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xf8, /* 11111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 218 0xda 'Ú' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1f, /* 00011111 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 219 0xdb 'Û' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 220 0xdc 'Ü' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
 
/* 221 0xdd 'Ý' */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
0xf0, /* 11110000 */
 
/* 222 0xde 'Þ' */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
0x0f, /* 00001111 */
 
/* 223 0xdf 'ß' */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0xff, /* 11111111 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 224 0xe0 'à' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xdc, /* 11011100 */
0x76, /* 01110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 225 0xe1 'á' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x78, /* 01111000 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xcc, /* 11001100 */
0xd8, /* 11011000 */
0xcc, /* 11001100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xcc, /* 11001100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 226 0xe2 'â' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 227 0xe3 'ã' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 228 0xe4 'ä' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 229 0xe5 'å' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 230 0xe6 'æ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
 
/* 231 0xe7 'ç' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 232 0xe8 'è' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 233 0xe9 'é' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xfe, /* 11111110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 234 0xea 'ê' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0xee, /* 11101110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 235 0xeb 'ë' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1e, /* 00011110 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x3e, /* 00111110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x66, /* 01100110 */
0x3c, /* 00111100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 236 0xec 'ì' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 237 0xed 'í' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x03, /* 00000011 */
0x06, /* 00000110 */
0x7e, /* 01111110 */
0xdb, /* 11011011 */
0xdb, /* 11011011 */
0xf3, /* 11110011 */
0x7e, /* 01111110 */
0x60, /* 01100000 */
0xc0, /* 11000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 238 0xee 'î' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x1c, /* 00011100 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x7c, /* 01111100 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 239 0xef 'ï' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7c, /* 01111100 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0xc6, /* 11000110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 240 0xf0 'ð' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0xfe, /* 11111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 241 0xf1 'ñ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x7e, /* 01111110 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 242 0xf2 'ò' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x06, /* 00000110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 243 0xf3 'ó' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x30, /* 00110000 */
0x60, /* 01100000 */
0x30, /* 00110000 */
0x18, /* 00011000 */
0x0c, /* 00001100 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 244 0xf4 'ô' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x0e, /* 00001110 */
0x1b, /* 00011011 */
0x1b, /* 00011011 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
 
/* 245 0xf5 'õ' */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0xd8, /* 11011000 */
0x70, /* 01110000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 246 0xf6 'ö' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 247 0xf7 '÷' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x76, /* 01110110 */
0xdc, /* 11011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 248 0xf8 'ø' */
0x00, /* 00000000 */
0x38, /* 00111000 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x38, /* 00111000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 249 0xf9 'ù' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 250 0xfa 'ú' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x18, /* 00011000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 251 0xfb 'û' */
0x00, /* 00000000 */
0x0f, /* 00001111 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0x0c, /* 00001100 */
0xec, /* 11101100 */
0x6c, /* 01101100 */
0x6c, /* 01101100 */
0x3c, /* 00111100 */
0x1c, /* 00011100 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 252 0xfc 'ü' */
0x00, /* 00000000 */
0x6c, /* 01101100 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x36, /* 00110110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 253 0xfd 'ý' */
0x00, /* 00000000 */
0x3c, /* 00111100 */
0x66, /* 01100110 */
0x0c, /* 00001100 */
0x18, /* 00011000 */
0x32, /* 00110010 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 254 0xfe 'þ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x7e, /* 01111110 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
/* 255 0xff 'ÿ' */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
 
uint8_t fb_font[FONT_GLYPHS][FONT_SCANLINES] = {
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xde, 0xde, 0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c, 0x0c, 0x0e, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00},
{0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x99, 0xa5, 0xa1, 0xa1, 0xa5, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x44, 0xba, 0xb2, 0xaa, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0x30, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf6, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x7f, 0xdb, 0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x6c, 0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x0c, 0x18, 0x3e, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0x36, 0xec, 0x18, 0x30, 0x66, 0xce, 0x9e, 0x3e, 0x06, 0x06, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x30, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x18, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x3c, 0x42, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7a, 0xc4, 0xce, 0xce, 0xd6, 0xd6, 0xe6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x6c, 0x66, 0x66, 0x66, 0x66, 0xec, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0x1c, 0x3c, 0x06, 0x7e, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xc4, 0xce, 0xd6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x7c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x0c, 0x18, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x0c, 0x18, 0x0e, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x3e, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x18, 0x30, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x6c, 0x38, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x18, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x18, 0x30, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x10, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xff, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7e, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7e, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x3c, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x3c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x30, 0x1c, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x30, 0x1c, 0x00},
{0x18, 0x18, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf7, 0x63, 0x63, 0x63, 0x63, 0x63, 0x63, 0x7b, 0x7b, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0xee, 0x66, 0x66, 0x66, 0x66, 0x66, 0xf6, 0x06, 0x66, 0x3c, 0x00},
{0x08, 0x1c, 0x22, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x0e, 0x1b, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x30, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x30},
{0x6c, 0x38, 0x10, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x66, 0x66, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x30, 0x30, 0x30, 0x36, 0x36, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x78, 0xe0, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x1e, 0x78, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x18, 0x18, 0x30},
{0x6c, 0x38, 0x10, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x60, 0xc0, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0xcc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6e, 0xd8, 0xd8, 0xd8, 0xde, 0xd8, 0xd8, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xd6, 0xd6, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x18, 0x18, 0x30},
{0x6c, 0x38, 0x10, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x18, 0x0c, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x10, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0xfc, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x78, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x66, 0xcc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x30, 0x60, 0x38, 0x00},
{0x10, 0x38, 0x44, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x66, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xb3, 0xb3, 0x33, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x64, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x62, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xe6, 0xe6, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xe0, 0xe0, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x06, 0x06, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x03, 0x3e, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x7e, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0xf6, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xb6, 0xb3, 0x33, 0x33, 0x33, 0x33, 0x33, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x4c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x4c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x18, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0xfe, 0xcc, 0x8c, 0x2c, 0x3c, 0x2c, 0x0c, 0x8c, 0xcc, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x06, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc2, 0xc0, 0x78, 0xc0, 0xc0, 0xc2, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xc0, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x32, 0x30, 0x78, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0xe0, 0x00},
{0x00, 0x03, 0x3e, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x38, 0x6c, 0x38, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xf3, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x6d, 0x6c, 0x78, 0x70, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc8, 0x38, 0x70, 0xd0, 0x38, 0x38, 0x6c, 0x64, 0xc6, 0xc2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0xec, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x76, 0x7e, 0x7e, 0x6e, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0xc0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x73, 0xdf, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x03, 0x03, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xdf, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x03, 0x03, 0x03, 0x00},
{0x00, 0x00, 0x7e, 0xb3, 0xb3, 0x33, 0x3e, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x7c, 0x66, 0x66, 0x7c, 0x78, 0x6c, 0x6c, 0xe6, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x38, 0x60, 0xc0, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x0c, 0x38, 0x60, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x62, 0x30, 0x18, 0x18, 0x30, 0x62, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x0c, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0x7e, 0xfe, 0x9a, 0x58, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00},
{0x03, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0x6c, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x63, 0xb3, 0xb3, 0x33, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0d, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x18, 0xf0, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x7e, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0xfc, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x30, 0x7c, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc0, 0x60, 0x30, 0x18, 0x7c, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0x60, 0x30, 0x78, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x7c, 0xc0, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0c, 0x7e, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x60, 0x60, 0x78, 0x0c, 0x06, 0x06, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x60, 0x78, 0x0c, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x18, 0x4c, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x70, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x1b, 0x0e, 0x04, 0xf7, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf5, 0xda, 0xd8, 0xdf, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3d, 0x1a, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0x6f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc7, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xcb, 0xf6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf3, 0x63, 0x60, 0x67, 0x63, 0x63, 0x63, 0x67, 0x6f, 0xff, 0x03, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0xe3, 0x63, 0x60, 0x67, 0x63, 0x63, 0x63, 0x63, 0x63, 0xf3, 0x03, 0x33, 0x1e, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xfb, 0xfb, 0xfb, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xf8, 0xff, 0xfb, 0xfb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x33, 0x1e, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0xb7, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x33, 0x1e, 0x00},
{0x6c, 0x38, 0x10, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x78, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x10, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x30, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x28, 0x10, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x78, 0x30, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x10, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x30, 0x30, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xdf, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x3e, 0xcc, 0x78, 0x00},
{0x6c, 0x38, 0x10, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x6c, 0x38, 0x10, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xe0, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x6c, 0x38, 0x10, 0xfe, 0x0c, 0x18, 0x30, 0x7c, 0x06, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00},
{0x00, 0x1b, 0x0e, 0x04, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0xf7, 0xd9, 0xd9, 0xda, 0xda, 0xda, 0xda, 0xdc, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0xd8, 0xd8, 0xdf, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0xf7, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0x6f, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xdb, 0xfb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x78, 0x70, 0x60, 0x60, 0x60, 0x60, 0xe0, 0x00},
{0x60, 0x30, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x38, 0x6c, 0x38, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x38, 0x6c, 0x38, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7a, 0xc4, 0xce, 0xce, 0xd6, 0xe6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7a, 0xc4, 0xce, 0xd6, 0xe6, 0x46, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x3c, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x18, 0x18, 0x30},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x1c, 0x74, 0x06, 0x06, 0x06, 0x06, 0x1c, 0xf0, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x0e, 0x3c, 0x06, 0x06, 0x1c, 0xf0, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0xc6, 0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc0, 0xfc, 0x06, 0x0c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc0, 0xfc, 0x06, 0x0c, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x7c, 0x00, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x72, 0x9c, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x00, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x3c, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x5c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xdc, 0xe6, 0x7c, 0x80, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0d, 0x06, 0x00},
{0x00, 0x00, 0x06, 0x0d, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x6c, 0x8e, 0x16, 0x26, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x78, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7a, 0xcd, 0x0d, 0x38, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xdc, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x06, 0x06, 0x1f, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0d, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x46, 0x6c, 0x2c, 0x2c, 0x38, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x64, 0x28, 0x38, 0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xdc, 0x6c, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x3c, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x7b, 0xde, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x78, 0x58, 0x3e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x7f, 0x63, 0x66, 0x6c, 0x7e, 0x63, 0xf3, 0x03, 0x33, 0x1e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6e, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0xc0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xd8, 0xd8, 0xde, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0xcc, 0xdc, 0x6c, 0x0c, 0x0d, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0x60, 0x60, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x66, 0x6c, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xfc, 0xc0, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x0e, 0x1b, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x98, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x0e, 0x1b, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x98, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x18, 0x18, 0x18, 0x18, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0xd8, 0x70, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x3b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xd6, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x60, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x06, 0x06, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x66, 0xcb, 0xfe, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x7e, 0xc7, 0x7c, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0x70, 0x30, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc3, 0xc3, 0xdb, 0xdb, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x76, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x7e, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x00, 0x1c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x7e, 0xcc, 0x78, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xcc, 0x6c, 0x3c, 0x3c, 0x6c, 0xcc, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x0d, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x1c, 0x18, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc0, 0x70, 0x30, 0xfc, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xda, 0xdc, 0x6f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xdb, 0xdb, 0xde, 0xde, 0xdb, 0x6b, 0x03, 0x1b, 0x0e, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x7f, 0xd9, 0xda, 0xda, 0xdb, 0xdd, 0x6f, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x60, 0x60, 0xf6, 0x6d, 0x6c, 0x66, 0x63, 0x6b, 0x36, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x26, 0x6d, 0x6c, 0xfc, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x3c, 0x0c, 0x2c, 0x18, 0x00},
{0x00, 0x00, 0x20, 0x60, 0x60, 0xf6, 0x6d, 0x6c, 0x6c, 0x6e, 0x6d, 0x36, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0xc0, 0xfe, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x03, 0x0e, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6d, 0x6c, 0x66, 0x63, 0x6b, 0xf6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6f, 0x6b, 0x63, 0x66, 0x6c, 0x6d, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0x7c, 0x6c, 0x28, 0xc6, 0xd6, 0x7c, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xf0, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xc0, 0xf0, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x00, 0x38, 0x18, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xb0, 0xd8, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0xd8, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0xd8, 0x68, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xd8, 0xd8, 0xf0, 0xd8, 0xd8, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xd6, 0x7c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd8, 0x78, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0xc0, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x70, 0xc0, 0x70, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0x70, 0x18, 0x70, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x20, 0x70, 0x70, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xd8, 0xd8, 0x70, 0x70, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x1c, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x6c, 0x6c, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x34, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00},
{0xc0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x20, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x20, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x34, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3e, 0x32, 0x30, 0x34, 0x3c, 0x34, 0x30, 0x30, 0x32, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x33, 0x33, 0x33, 0x33, 0x3f, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x3e, 0x63, 0x63, 0x63, 0x63, 0x63, 0x36, 0x36, 0x36, 0x77, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x6c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x82, 0x44, 0x7c, 0x44, 0x00, 0x82, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x62, 0x30, 0x18, 0x18, 0x30, 0x62, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x92, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc0, 0x78, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x6c, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x6c, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x46, 0x6c, 0x2c, 0x2c, 0x38, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x30, 0x18, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0x78, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x46, 0x7c, 0x18, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0x20, 0x30, 0x10, 0x38, 0x38, 0x6c, 0x64, 0xc6, 0xc2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xf6, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x66, 0x6c, 0x3c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x3c, 0x30, 0x60, 0x3c, 0x60, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x46, 0x2c, 0x2c, 0x18, 0x30, 0x68, 0x68, 0xc4, 0xc2, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xcc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x6c, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x36, 0x1e, 0xc6, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc2, 0x65, 0x24, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0xc0, 0x21, 0x32, 0x12, 0x1c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc2, 0x65, 0x24, 0x38, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xa6, 0x2c, 0x38, 0x68, 0xca, 0xc4, 0x0c, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0x60, 0x3c, 0x06, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x7c, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x78, 0x68, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x32, 0x30, 0x30, 0x3c, 0x34, 0x30, 0x30, 0x30, 0x30, 0x00},
{0x00, 0x60, 0x30, 0x30, 0x60, 0x63, 0xff, 0xc6, 0x06, 0x0c, 0x0c, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x60, 0x60, 0xfe, 0xfe, 0x0c, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xac, 0x26, 0x26, 0x0b, 0x0b, 0x1b, 0x1b, 0x1b, 0x1b, 0x03, 0x02, 0x04, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x28, 0x4c, 0x14, 0x24, 0x06, 0x02, 0x02, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6d, 0x03, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6d, 0x03, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xd6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x36, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x06, 0x76, 0x9c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x7c, 0xd6, 0x66, 0x06, 0x06, 0x66, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x06, 0x3c, 0x60, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x26, 0x1c, 0x70, 0xc0, 0xc2, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0x68, 0x38, 0x30, 0x38, 0x38, 0x4c, 0x4c, 0x86, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xba, 0x30, 0x38, 0x28, 0x4c, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xc0, 0xcc, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xc0, 0xdc, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x7e, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x1c, 0x18, 0x7e, 0x58, 0x18, 0x18, 0x18, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0xa6, 0x2c, 0x38, 0x68, 0xca, 0xc4, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xfc, 0xc0, 0x60, 0x3c, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x30, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xb2, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x03, 0x06, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xf8, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x66, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xd8, 0xd8, 0xd8, 0xde, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xd8, 0xfe, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xb2, 0x30, 0x3e, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x18, 0x00, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x38, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfe, 0xc6, 0x82, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0xc6, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfe, 0x06, 0x02, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xff, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xb0, 0xb0, 0x30, 0x3c, 0x36, 0x36, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x3e, 0x06, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x9c, 0xb6, 0xb6, 0xb6, 0xf6, 0xb6, 0xb6, 0xb6, 0xb6, 0x9c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xcc, 0xcc, 0xcc, 0x7c, 0x6c, 0x6c, 0x6c, 0x6c, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x7c, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfe, 0xc6, 0x82, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xfe, 0x06, 0x02, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xff, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xb0, 0x30, 0x3c, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3e, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x9c, 0xb6, 0xb6, 0xf6, 0xb6, 0xb6, 0x9c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xcc, 0xcc, 0x7c, 0x6c, 0x6c, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x06, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xf8, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xd8, 0xd8, 0xde, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xfe, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf8, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x38, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0xfc, 0xb4, 0x30, 0x3c, 0x36, 0x36, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x30, 0xfc, 0xb4, 0x30, 0x3c, 0x36, 0x36, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xce, 0xdb, 0xd9, 0xd8, 0xfe, 0xd8, 0xd8, 0xd9, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xce, 0xdb, 0xd8, 0xfe, 0xd8, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0x6c, 0xfe, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x6c, 0x7c, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x88, 0x8c, 0x9c, 0x96, 0xf6, 0xb6, 0xbf, 0xab, 0xeb, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8c, 0x9c, 0xf6, 0xbe, 0xab, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x6c, 0x6c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x6c, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xa3, 0xb2, 0x96, 0xfc, 0x9c, 0xbe, 0xaa, 0xab, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xbf, 0xa3, 0x96, 0xfe, 0xab, 0xab, 0xeb, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x10, 0x7c, 0xc6, 0x06, 0x06, 0x7c, 0x06, 0x06, 0x06, 0x7c, 0xc0, 0x7c, 0x00, 0x00},
{0x00, 0x6c, 0x38, 0x10, 0x00, 0x7c, 0x86, 0x06, 0x7c, 0x06, 0x06, 0x7c, 0xc0, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x96, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x96, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc2, 0xc6, 0xc6, 0xc4, 0xcc, 0x6c, 0x68, 0x78, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x64, 0x6c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0x66, 0x00, 0xc2, 0xc6, 0xc4, 0xc4, 0x6c, 0x68, 0x78, 0x38, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0x66, 0x00, 0xc2, 0xc6, 0x64, 0x6c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd8, 0xd8, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6f, 0x03, 0x06, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x6f, 0x03, 0x06, 0x1c, 0x00},
{0x00, 0x10, 0x7c, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0x7c, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x7c, 0xd6, 0xc6, 0xc6, 0xc6, 0xd6, 0x7c, 0x10, 0x00, 0x00, 0x00},
{0x04, 0x7c, 0x40, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x7c, 0x40, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x7c, 0x54, 0x00, 0x6c, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x54, 0x00, 0x6c, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x60, 0x3c, 0x0c, 0x0c, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc0, 0x78, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x3c, 0x0f, 0x18, 0x18, 0xf0, 0x3c, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x7c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x24, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x40, 0x7c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x7c, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x66, 0x00, 0xc3, 0x00, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x50, 0x46, 0x00, 0x82, 0x41, 0x00, 0x62, 0x0a, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0xc6, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0xf0, 0x60, 0x60, 0x7c, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x6e, 0x64, 0x7a, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x6e, 0x64, 0x7a, 0x60, 0x60, 0xf0, 0x00},
{0x02, 0x06, 0xfe, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x02, 0x06, 0xfe, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0xf8, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0xf8, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xf6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x78, 0x6c, 0x66, 0xf6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x30, 0x60, 0x38, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xd6, 0xd6, 0xdc, 0xf8, 0xdc, 0xd6, 0xd6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xdc, 0xf8, 0xdc, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0xf6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0xf0, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf3, 0xb3, 0xb3, 0x36, 0x3c, 0x3c, 0x36, 0x33, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf3, 0xb6, 0xbc, 0x3c, 0x36, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xdf, 0xdb, 0xd9, 0xd8, 0xf8, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdf, 0xdb, 0xd9, 0xf8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xd8, 0xd8, 0xd8, 0xde, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x03, 0x0b, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xfe, 0xdb, 0xdb, 0xdb, 0x03, 0x0b, 0x06, 0x00},
{0x00, 0x00, 0x7c, 0xc2, 0xcc, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xcc, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc2, 0xcc, 0xd6, 0xd6, 0xcc, 0x7a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x0c, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x0c, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x3c, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x3c, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xf6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7f, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7f, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0x7e, 0x16, 0x16, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xd6, 0xd6, 0x7e, 0x16, 0x16, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x33, 0xb3, 0xb3, 0x7f, 0x30, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0xb3, 0x7f, 0x30, 0x30, 0x33, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x33, 0xb3, 0xb3, 0x7f, 0x30, 0x30, 0x30, 0x33, 0x1e, 0x0c, 0x18, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0xb3, 0x7f, 0x30, 0x30, 0x33, 0x1e, 0x0c, 0x18, 0x0e, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x06, 0x16, 0x0c, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0e, 0x0c, 0x08, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x0e, 0x0c, 0x08, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc7, 0x03, 0x01, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x6c, 0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x76, 0x36, 0x7e, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x06, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0xfe, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0x38, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xd6, 0xd6, 0xd6, 0x7c, 0xd6, 0xd6, 0xd6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x86, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x86, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x0c, 0x18, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00},
{0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xce, 0xde, 0xfe, 0xf6, 0xe6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x3e, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x7c, 0xc6, 0x06, 0x3e, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x66, 0xcc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc3, 0xc3, 0xc3, 0xf3, 0xdb, 0xdb, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x7c, 0xcd, 0xcd, 0xcd, 0xcd, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcd, 0xcd, 0xcd, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x8c, 0x0c, 0x38, 0x0d, 0x0d, 0x0d, 0x0d, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0x0c, 0x39, 0x0d, 0x0d, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0x86, 0x06, 0x3c, 0x06, 0x06, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x06, 0x3c, 0x06, 0x06, 0x07, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0x6d, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x6d, 0x6d, 0x6d, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xfc, 0xcd, 0xcd, 0xcd, 0xcd, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xfd, 0xcd, 0xcd, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xce, 0xc6, 0xc6, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xce, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x1b, 0x1b, 0x1b, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x5a, 0x18, 0x1b, 0x1b, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x64, 0x94, 0xba, 0x52, 0x4c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x7b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x7f, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x7e, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x0c, 0xd8, 0xfe, 0xc3, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7c, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xcf, 0xd6, 0xd6, 0xd6, 0xd6, 0xcc, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x7f, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7c, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xf6, 0xd6, 0xd6, 0xd6, 0xd6, 0xcc, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0x7f, 0x24, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0xf0, 0x3c, 0x0e, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x6c, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0c, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x30, 0x60, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcf, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x06, 0x06, 0x7c, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x06, 0x3e, 0x66, 0x60, 0x60, 0x60, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x06, 0x06, 0x06, 0x6c, 0x38, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x16, 0x16, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x76, 0x1e, 0x0e, 0x0c, 0xd8, 0xfe, 0xc3, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x30, 0x18, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x06, 0x06, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x63, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xfe, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd0, 0xd0, 0xd0, 0x7c, 0x16, 0x16, 0x16, 0xd6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x3c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x6a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7f, 0x0c, 0x0c, 0x0c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x0c, 0x0c, 0x0c, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x0f, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x7c, 0x60, 0x60, 0x60, 0x60, 0x60, 0x78, 0x0c, 0x18, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x7e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xc6, 0xc6, 0xcf, 0xd6, 0xd6, 0xcc, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x7f, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xf6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xca, 0xc0, 0xc0, 0xc0, 0x00},
{0x00, 0x00, 0x60, 0x38, 0x0c, 0x7f, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x60, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x1c, 0x0c, 0x18, 0x3c, 0x64, 0x66, 0x62, 0x63, 0x3d, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x0c, 0x0c, 0x0f, 0x00},
{0x00, 0x00, 0x0e, 0x18, 0x30, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0f, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x3e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x3e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x7e, 0x06, 0x06, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x76, 0x1c, 0x18, 0x30, 0x60, 0x3e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcf, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x0f, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3e, 0x06, 0x66, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0xdc, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0x76, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0xfe, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xd0, 0xd0, 0x7c, 0x16, 0x16, 0x16, 0x16, 0xd6, 0x7c, 0x10, 0x10, 0x10, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xcc, 0xcc, 0xcc, 0xcc, 0x77, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x6c},
{0x18, 0x00, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x38, 0x10, 0x38, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x60, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0c, 0x00},
{0x10, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x74, 0xd6, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x18, 0x30, 0x00},
{0x0c, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x06, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1b, 0x36, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x44, 0xaa, 0x6c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x0a, 0x0c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x50, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x3c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x6c, 0xd8, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x08, 0x30},
{0x60, 0x30, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0xa0, 0x60, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x38, 0x10, 0x10},
{0x18, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x06, 0x03, 0x00},
{0x48, 0xa8, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0x00, 0x33, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x06, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0x60, 0x66, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x18},
{0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x18, 0x03, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x7e, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x66, 0x76, 0xdc, 0xcc, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x0c, 0x0c, 0x0c, 0x1c, 0x36, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0xd6, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0x06, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0xc6, 0xc6, 0xc6, 0xc6, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xee, 0x66, 0x66, 0x66, 0x66, 0x66, 0x2c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x4c, 0xcc, 0xcc, 0xec, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0e, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x46, 0xc6, 0xc6, 0xe6, 0x06, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xee, 0x66, 0x66, 0x6c, 0x78, 0x60, 0x60, 0x60, 0x60, 0x60, 0x70, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xee, 0x66, 0x66, 0x34, 0x18, 0x0c, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x66, 0x64, 0x6c, 0x6e, 0x60, 0x60, 0x60, 0x60, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xf6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe6, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x66, 0x66, 0xc6, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x22, 0x20, 0x10, 0x08, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x20, 0x1e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x3c, 0x40, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x20, 0x1c, 0x20, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x18, 0x20, 0x1c, 0x20, 0x00, 0x00},
{0x00, 0x30, 0x40, 0x38, 0x40, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x28, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x88, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x40, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x3c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x40, 0x30, 0x4e, 0x49, 0x39, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x24, 0x00},
{0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x12, 0xca, 0x2c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00},
{0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x14, 0x0c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00},
{0x0a, 0x2a, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x7e, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x10, 0x0c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x10, 0x0c, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x70, 0x70, 0x38, 0x18, 0x18, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x44, 0xfc, 0xf8, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4a, 0xfe, 0xf4, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x20, 0x40, 0x30, 0x10, 0x20, 0x42, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x2c, 0x44, 0x42, 0x82, 0x82, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xf8, 0x78, 0x08, 0x08, 0x08, 0x0c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x82, 0xc6, 0xc6, 0x6c, 0x28, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x38, 0x28, 0x6c, 0xc6, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xf8, 0x88, 0xf8, 0x78, 0x08, 0x0c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x91, 0x92, 0x64, 0x08, 0x10, 0x26, 0x49, 0x89, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x18, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0xfe, 0x7c, 0x38, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x29, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x28, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x06, 0x28, 0x5e, 0x00, 0x00, 0x00},
{0x00, 0x07, 0x08, 0x07, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x04, 0x03, 0x14, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x04, 0x03, 0x04, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x23, 0x54, 0x33, 0x24, 0x40, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x04, 0x03, 0x04, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0x81, 0x7e, 0x08, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x08, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00},
{0x06, 0x08, 0x06, 0x08, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x08, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x94, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x88, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x94, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x08, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x08, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x1c, 0x6a, 0x04, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x14, 0x08, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x12, 0x04, 0x18, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x00, 0x01, 0x15, 0x88, 0x88, 0x8a, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x88, 0x90, 0x65, 0x00, 0x02, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x00, 0x0a, 0x00, 0x01, 0x15, 0x88, 0x88, 0x90, 0x65, 0x00, 0x02, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x90, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x2a, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x00, 0x50, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00},
{0x0a, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x20, 0x40, 0x3e, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x05, 0x0b, 0x48, 0x84, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x29, 0x01, 0x19, 0x21, 0x19, 0xa1, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x05, 0x0b, 0x48, 0x84, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa4, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x44, 0x09, 0xa2, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x08, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x02, 0x2a, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x14, 0x00, 0x08, 0x00},
{0x00, 0x08, 0x00, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x08, 0x14, 0x08, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0x3c, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x38, 0x40, 0x38, 0x40, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x40, 0x38, 0x40, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x12, 0x2c, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x3c, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x18, 0x10, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x08, 0x08, 0x08, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x20, 0x47, 0x88, 0x08, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x50, 0x20, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x08, 0x00, 0x08},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x14, 0x00, 0x08},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x80, 0x60, 0x80, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x40, 0x43, 0x55, 0x7e, 0x80, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x2a, 0x20, 0x26, 0x2a, 0x7c, 0x80, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0e, 0x1c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x14, 0x08, 0x14, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x2c, 0x10, 0x28, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x15, 0x8a, 0x90, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x5a, 0xa5, 0x66, 0x5b, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x5a, 0x66, 0xa5, 0x5a, 0x00},
{0x00, 0x00, 0x18, 0x66, 0x42, 0x42, 0x81, 0x99, 0x99, 0x81, 0x42, 0x42, 0x66, 0x18, 0x00, 0x00},
{0x08, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x26, 0x08, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x8a, 0x90, 0x60},
{0x32, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x0c, 0x04, 0x08, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x30, 0x40, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x54, 0xaa, 0x92, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x82, 0xfe, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x22, 0x14, 0x08},
{0x08, 0x14, 0x22, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x0c, 0x10, 0x10, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x70, 0x70, 0x38, 0x18, 0x18, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x44, 0xfc, 0xf8, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4a, 0xfe, 0xf4, 0x60, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4e, 0xf0, 0xfe, 0x7c, 0x30, 0x30, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x38, 0x2c, 0x44, 0x42, 0x82, 0x92, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x60, 0x7e, 0x3c, 0x30, 0x60, 0x40, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x82, 0xc6, 0xc6, 0x6c, 0x28, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x10, 0x38, 0x28, 0x6c, 0xc6, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xf8, 0x88, 0xf8, 0x78, 0x08, 0x0c, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x88, 0x88, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x72, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x40, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x88, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x20, 0x1e, 0x20, 0x00, 0x14, 0x14, 0x14, 0x14, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x3c, 0x40, 0x54, 0x54, 0x54, 0x54, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x92, 0x92, 0x4c, 0x30, 0x4c, 0x02, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x92, 0x92, 0x64, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0xaa, 0xaa, 0xaa, 0x82, 0x82, 0x40, 0x30, 0x4c, 0x02, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x82, 0x82, 0x44, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x92, 0x92, 0x82, 0x82, 0x40, 0x30, 0x4c, 0x02, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x38, 0x6c, 0x38},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x38, 0x6c, 0x38},
{0x18, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x0c, 0xec, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x7c, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x30, 0x30, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x60, 0x0c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x30, 0x18, 0x70, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x30, 0x18, 0x70, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x10, 0x38, 0x6c, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x76, 0xdc, 0x00},
{0x6c, 0x38, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x18, 0x0c, 0x38, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x18, 0x0c, 0x38, 0x00},
{0x18, 0x18, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x38, 0x6c, 0x64, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xe0, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x60, 0x30, 0xe0, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x30, 0x18, 0x70, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x6c, 0x38, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x76, 0xdc, 0x00},
{0x0c, 0x18, 0x66, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x66, 0x66, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x0c, 0xec, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x7c, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x7c, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x10, 0x38, 0x6c, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x10, 0x38, 0x6c, 0x00},
{0x0c, 0x18, 0x72, 0x9c, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x00, 0x72, 0x9c, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0x7c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x18, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00},
{0x18, 0x18, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x7c, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x7c, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x60, 0x6c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0x70, 0x1c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x60, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x44, 0x38, 0x10, 0x7c, 0xc6, 0xc6, 0x70, 0x1c, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x44, 0x38, 0x10, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x7c, 0xc6, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0x7c, 0xc6, 0x60, 0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x18, 0x18, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x16, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x7e, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x10, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x08, 0x1c, 0x36, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x6c, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x6c, 0x6c, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x76, 0xdc, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x10, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x10, 0x38, 0x6c, 0x00},
{0x0c, 0x18, 0x72, 0x9c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x76, 0xdc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x00, 0x7c, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xcc, 0xcc, 0x00, 0xfc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x18, 0x18, 0x00},
{0x60, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0xee, 0x6c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x30, 0x30, 0x00},
{0x30, 0x30, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x10, 0x38, 0x44, 0xfe, 0xc6, 0x8c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc2, 0xc6, 0xfe, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x60, 0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x7c, 0x00, 0x00},
{0x6c, 0x6c, 0x00, 0x10, 0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xd6, 0xd6, 0xd6, 0xfe, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x6c, 0x38, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x18, 0x0c, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x30, 0x00, 0x38, 0x6c, 0x64, 0x60, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x16, 0x38, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x16, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x68, 0x1c, 0x36, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x68, 0x1c, 0x36, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x28, 0x54, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x6c, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x0c, 0x18, 0x44, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x18, 0x44, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x44, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x30, 0x44, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x08, 0x54, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x08, 0x54, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x72, 0x9c, 0x44, 0x38, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x72, 0x9c, 0x44, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x6c, 0x38, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x6c, 0x38, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x23, 0x76, 0x88, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x26, 0x70, 0xd8, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc4, 0x6e, 0x11, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x64, 0x0e, 0x1b, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0xfe, 0x62, 0x68, 0x78, 0x68, 0x62, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x62, 0x66, 0xfe, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x23, 0x76, 0x88, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x26, 0x70, 0xd8, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc4, 0x6e, 0x11, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0xc0, 0x64, 0x0e, 0x1b, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0e, 0x13, 0x3a, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x28, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x76, 0xdc, 0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x38, 0x44, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x18, 0x33, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1b, 0x33, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x33, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x63, 0x33, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x70, 0x1b, 0x33, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x1b, 0x33, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x68, 0xb3, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x68, 0xb3, 0x03, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0x7a, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x38, 0x0c, 0x18, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x18, 0x30, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x33, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1b, 0x33, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x33, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x63, 0x33, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x70, 0x1b, 0x33, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0x1b, 0x33, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x68, 0xb3, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x68, 0xb3, 0x03, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x03, 0x03, 0xce, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x30, 0x30, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x30, 0x30, 0x00},
{0x30, 0x18, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x30, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x18, 0x18, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x0c, 0x18, 0xf6, 0x06, 0x00},
{0x38, 0x0c, 0x18, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x38, 0x0c, 0x18, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x3a, 0x5c, 0x00, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x76, 0xdc, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00},
{0x00, 0x18, 0x18, 0x30, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x6c, 0xc6, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xcc, 0x66, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x66, 0xcc, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc6, 0x6c, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x34, 0x58, 0x0c, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x34, 0x58, 0x30, 0x18, 0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0xfe, 0x00, 0xa4, 0xaa, 0xea, 0xea, 0xa6, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xa4, 0xea, 0xaa, 0xaa, 0xa6, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x8a, 0xce, 0x8e, 0xea, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x8e, 0xca, 0x8a, 0xea, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xca, 0x2e, 0x4a, 0x2a, 0xca, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xaa, 0xae, 0xea, 0x2a, 0x2a, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x6a, 0x8e, 0xca, 0xaa, 0x4a, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x38, 0x20, 0x30, 0x20, 0x20, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x30, 0x28, 0x30, 0x20, 0x20, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x4a, 0x4e, 0x4a, 0x4a, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x28, 0x28, 0x38, 0x28, 0x28, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x2a, 0x4e, 0x8e, 0xee, 0x00, 0x6c, 0x8a, 0x4c, 0x28, 0xc8, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x2a, 0x4e, 0x8e, 0xee, 0x00, 0xa2, 0xa2, 0xe2, 0xea, 0xa4, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xea, 0x2a, 0x4e, 0x8e, 0xee, 0x00, 0x08, 0x08, 0x08, 0x28, 0x10, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0x80, 0x80, 0x80, 0xf0, 0x28, 0x30, 0x28, 0x0a, 0x0e, 0x0e, 0x0a, 0x00, 0xfe, 0x00},
{0xfe, 0x00, 0xc0, 0xa0, 0xc0, 0xa0, 0x20, 0x20, 0x38, 0x0a, 0x0e, 0x0e, 0x0a, 0x00, 0xfe, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x9c, 0xd2, 0xbc, 0x92, 0x9c, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x00},
{0x00, 0x18, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00},
{0x00, 0x30, 0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00},
{0x00, 0xcc, 0xcc, 0xcc, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x38, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc6, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x6b, 0x6b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x92, 0x44, 0x28, 0x92, 0x28, 0x44, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xc3, 0xdb, 0x1b, 0x1e, 0x1c, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x7c, 0x00, 0x00},
{0x7c, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x38, 0x6c, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x28, 0x00, 0x00, 0x44, 0xee, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7b, 0xcf, 0xcf, 0x1b, 0x33, 0x33, 0x33, 0x00, 0x33, 0x33, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xde, 0xf3, 0xf3, 0xc6, 0xcc, 0xcc, 0xcc, 0x00, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x06, 0x06, 0x0c, 0x0c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xdb, 0xdb, 0xdb, 0xde, 0xd8, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x3e, 0x72, 0xf2, 0xf2, 0xf2, 0x72, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x9c, 0x9e, 0x9e, 0x9e, 0x9c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x18, 0x38, 0x78, 0xd8, 0xfc, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xf8, 0xc0, 0xf0, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x78, 0xc0, 0xf0, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xf8, 0xd8, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0x70, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd8, 0xd8, 0x78, 0x18, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x60, 0x60, 0x60, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x60, 0x30, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xb0, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x70, 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0xd8, 0xfc, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xc0, 0xf0, 0x18, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0xc0, 0xf0, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xd8, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x70, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xd8, 0x78, 0x18, 0xf0, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x30, 0xfc, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0x60, 0x60, 0x60, 0x30, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xb0, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0xc0, 0xcf, 0xcc, 0xcc, 0x7f, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x04, 0x7c, 0xce, 0xc8, 0xc8, 0xd0, 0xd0, 0xd0, 0xe0, 0xe6, 0x7c, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xd6, 0xd8, 0xd8, 0xd8, 0xde, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xc0, 0xc0, 0xc0, 0xf0, 0xcd, 0xce, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x60, 0xf8, 0x60, 0xf8, 0x60, 0x60, 0xe6, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0xec, 0xd6, 0xde, 0xd6, 0xd6, 0xf6, 0xd6, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x66, 0x76, 0xff, 0x76, 0x6e, 0xff, 0x6e, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xf8, 0xe0, 0xf3, 0xd6, 0xdb, 0xce, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x81, 0x81, 0x81, 0x5a, 0xff, 0x5a, 0xff, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf2, 0x8a, 0xaa, 0xaa, 0xaa, 0xaa, 0xa2, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x3e, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x7c, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x60, 0xfc, 0x60, 0xf8, 0x60, 0x60, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x6c, 0x78, 0xfe, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x7e, 0x5a, 0x18, 0x1e, 0x78, 0x1e, 0x78, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x7c, 0xb6, 0x36, 0x33, 0x33, 0x33, 0x63, 0x66, 0xf6, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd0, 0xd2, 0xd6, 0x7c, 0x18, 0x30, 0x6e, 0xd8, 0x98, 0x18, 0x0e, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xd0, 0xd2, 0xd6, 0x7c, 0x18, 0x30, 0x6e, 0xd8, 0x8c, 0x06, 0x1c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x62, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0xa0, 0x62, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4e, 0xb9, 0x58, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x7c, 0xda, 0xd8, 0xd8, 0xda, 0x7c, 0x19, 0x3f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xc0, 0xc2, 0xc6, 0x7c, 0x18, 0x30, 0x6e, 0xdb, 0x9b, 0x1b, 0x0e, 0x00, 0x00, 0x00},
{0x00, 0x70, 0xc0, 0xc2, 0xc6, 0x7c, 0x18, 0x30, 0x7b, 0xdb, 0x9b, 0x1b, 0x0d, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc2, 0xc0, 0x78, 0xc0, 0xc0, 0xc2, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x26, 0x3e, 0x26, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7f, 0xb9, 0x58, 0x1a, 0x1e, 0x1a, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1a, 0x66, 0x46, 0x87, 0x8c, 0x8c, 0x7c, 0x98, 0x98, 0x70, 0x00},
{0x00, 0x00, 0x52, 0xb5, 0x15, 0x16, 0x2c, 0x34, 0x68, 0xa9, 0xaa, 0x4c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x48, 0xb0, 0x80, 0x48, 0x7c, 0x66, 0x26, 0x26, 0xa6, 0x46, 0x06, 0x34, 0x48, 0x00},
{0x00, 0x00, 0xe2, 0xa2, 0xa2, 0xa2, 0xbe, 0xa2, 0xa2, 0xa2, 0xa2, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x36, 0x3b, 0x3b, 0x33, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x1e, 0x18, 0x76, 0x3b, 0x3b, 0x33, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x33, 0x4e, 0x06, 0x06, 0x0c, 0x0c, 0x1f, 0x6c, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x71, 0x8e, 0x04, 0x0c, 0x06, 0x03, 0x63, 0xc3, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x46, 0x49, 0x39, 0x1e, 0x18, 0x30, 0x70, 0xb1, 0xba, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x19, 0x31, 0x32, 0x64, 0x68, 0x70, 0xe1, 0x66, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xff, 0xd8, 0xde, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xde, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe2, 0xa2, 0xb2, 0xb2, 0xaa, 0xaa, 0xa6, 0xa6, 0xa2, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xcc, 0xcf, 0xed, 0xff, 0xfc, 0xdf, 0xcc, 0xcc, 0xcc, 0xcc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0xb9, 0xa5, 0xa5, 0xb9, 0xa1, 0xa1, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x40, 0x8e, 0x93, 0xa3, 0x63, 0x4b, 0x6a, 0xa4, 0xb0, 0xb0, 0x60, 0x00},
{0x00, 0x00, 0xfc, 0xa2, 0xa2, 0xa2, 0xa2, 0xbc, 0xa0, 0xa0, 0xa0, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xa2, 0xaa, 0xa6, 0x7e, 0x01, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x4d, 0x4d, 0x19, 0x1e, 0x1c, 0x34, 0x34, 0xb5, 0x62, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x58, 0xa6, 0xa3, 0x6c, 0xb8, 0x26, 0x26, 0x26, 0xa7, 0xc2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0xa2, 0xa2, 0xa2, 0xa2, 0xbc, 0xb0, 0xa8, 0xa4, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c, 0x6d, 0x67, 0x66, 0xee, 0x08, 0x00, 0x00, 0x00},
{0x30, 0x0c, 0xfc, 0xc6, 0xc6, 0xc6, 0xfc, 0xd8, 0xdc, 0xdc, 0xe6, 0xe6, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x71, 0xdb, 0x35, 0xd1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x52, 0x5a, 0x52, 0x5f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf1, 0x5b, 0x55, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x18, 0xce, 0xd6, 0xd6, 0xd6, 0xd6, 0xd6, 0xe6, 0x6c, 0x38, 0x50, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x0a, 0x14, 0x14, 0x28, 0x28, 0x50, 0x50, 0xa0, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x9c, 0x30, 0xfe, 0x0c, 0x18, 0x38, 0x0c, 0x06, 0x06, 0xc6, 0xc6, 0x7c, 0x00},
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0x6c, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x26, 0x03, 0x13, 0x0c, 0x13, 0x03, 0x03, 0x66, 0x98, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x6c, 0x38, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xfe, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x2d, 0x2d, 0x1a, 0x1e, 0x1b, 0x31, 0x31, 0xb2, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x6b, 0xc8, 0xcc, 0xc6, 0xc6, 0xcc, 0xc0, 0x63, 0x1c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xe7, 0xff, 0xe0, 0x67, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x26, 0x44, 0xf8, 0xc0, 0xc8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x4c, 0x52, 0x3c, 0x10, 0x3c, 0x60, 0xc0, 0xc3, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x73, 0xce, 0x18, 0x3a, 0x5c, 0x18, 0x30, 0x30, 0xb0, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x0c, 0x0c, 0x0c, 0x2c, 0x3c, 0x2c, 0x8c, 0xcc, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x12, 0x12, 0x12, 0x16, 0x36, 0x3e, 0x3a, 0x5a, 0x52, 0x91, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x26, 0x46, 0xc6, 0xc4, 0xc8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x42, 0xc6, 0xe7, 0x7a, 0x38, 0x5c, 0xce, 0xe7, 0x63, 0xe2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xfc, 0x7e, 0x06, 0x06, 0x06, 0x06, 0x0c, 0x7e, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x40, 0x78, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1e, 0x7e, 0xf2, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xfe, 0x7e, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x38, 0x00, 0x78, 0x38, 0x38, 0x38, 0x38, 0x38, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7d, 0xff, 0x83, 0x86, 0x82, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0xc6, 0xfc, 0x18, 0x30, 0x60, 0xdc, 0x86, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0xc6, 0xfc, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0x36, 0xec, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0x30, 0x70, 0xb2, 0xf6, 0x3c, 0x18, 0x30, 0x60, 0xde, 0x98, 0x1c, 0x06, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0xb0, 0x3c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xf0, 0xc0, 0xe2, 0x36, 0xec, 0x18, 0x30, 0x60, 0xdc, 0xb0, 0x3c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xe0, 0x30, 0x62, 0x36, 0xec, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xf0, 0x80, 0xe2, 0x36, 0xec, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xf0, 0x30, 0x62, 0x66, 0x6c, 0x18, 0x30, 0x60, 0xdc, 0xb6, 0x1c, 0x36, 0x1c, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0xce, 0xc4, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x73, 0x23, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x95, 0x65, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0xb5, 0x55, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xce, 0xce, 0xce, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x7c, 0x38, 0x38, 0x7c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0xdb, 0x73, 0x73, 0x73, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x95, 0x95, 0x95, 0x65, 0x65, 0x65, 0x95, 0x95, 0x95, 0x95, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xee, 0xfe, 0xfe, 0xd6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xdb, 0xdb, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xce, 0xc4, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x73, 0x23, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x05, 0x05, 0x00, 0x95, 0x95, 0x95, 0x95, 0x95, 0x65, 0x65, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x15, 0x15, 0x00, 0xb5, 0xb5, 0xb5, 0xb5, 0x55, 0x55, 0x55, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0x00, 0xdb, 0xdb, 0xce, 0xce, 0xce, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x6c, 0x38, 0x38, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0xdb, 0xdb, 0x73, 0x73, 0x73, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x05, 0x05, 0x00, 0x95, 0x95, 0x65, 0x65, 0x95, 0x95, 0x95, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xec, 0xfe, 0xd6, 0xd6, 0xd6, 0xd6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x5a, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0x5a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xcc, 0xe6, 0xd6, 0xd6, 0xd6, 0xd6, 0xe6, 0xcc, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x5a, 0x99, 0xbd, 0xdb, 0xdb, 0xbd, 0x99, 0x5a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0xcc, 0x86, 0x06, 0x06, 0x06, 0x06, 0x86, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf0, 0xe0, 0xb0, 0x18, 0x0c, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0f, 0x07, 0x0d, 0x18, 0x30, 0x60, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0x60, 0x30, 0x18, 0x0d, 0x07, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x06, 0x0c, 0x18, 0xb0, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x62, 0xff, 0x64, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x26, 0xff, 0x46, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0xce, 0xbb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x73, 0xdd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xff, 0x6c, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x6c, 0x36, 0xff, 0x36, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x66, 0xfc, 0x66, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x66, 0x3f, 0x66, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x63, 0xff, 0x63, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xc6, 0xff, 0xc6, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x33, 0x63, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0xcc, 0xc6, 0x7f, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x3b, 0x6b, 0xfe, 0x68, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x60, 0xdc, 0xd6, 0x7f, 0x16, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x5a, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x6e, 0xff, 0x76, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x30, 0x60, 0x63, 0xff, 0xc6, 0x16, 0x1c, 0x1c, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x66, 0x36, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x0c, 0xfe, 0xcc, 0xd8, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x06, 0x06, 0x06, 0x36, 0x66, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xd8, 0xcc, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x0c, 0x0c, 0x3f, 0x1e, 0x0c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x36, 0x66, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x30, 0xfc, 0x78, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0x0c, 0x3f, 0x1e, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x00, 0xf0, 0xe0, 0xb0, 0x18, 0x0c, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x98, 0xb0, 0xff, 0xb0, 0x98, 0x19, 0x0d, 0xff, 0x0d, 0x19, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x1e, 0x1c, 0x16, 0x03, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x78, 0x38, 0x68, 0xc0, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x1c, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1e, 0x1c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x06, 0xff, 0x06, 0x0c, 0x30, 0x60, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x2e, 0x3f, 0x24, 0x24, 0x24, 0x24, 0xfc, 0x74, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x60, 0xff, 0x60, 0x30, 0x0c, 0x06, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x7e, 0xff, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0xff, 0x7e, 0x24, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xff, 0x00, 0xff, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xff, 0x00, 0xff, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x7f, 0xc4, 0x7f, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x7e, 0xcb, 0x7e, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0xfe, 0x23, 0xfe, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x7f, 0xc0, 0x7f, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x7c, 0xee, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xfe, 0x03, 0xfe, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x7e, 0xc3, 0x7e, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x7c, 0xee, 0x6c, 0x6c, 0x6c, 0x6c, 0xee, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf0, 0xe0, 0xb0, 0xd8, 0xec, 0xb6, 0x1b, 0x0c, 0x04, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0f, 0x07, 0x0d, 0x1b, 0x37, 0x6d, 0xd8, 0x30, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x20, 0x30, 0xd8, 0x6d, 0x37, 0x1b, 0x0d, 0x07, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x0c, 0x1b, 0xb6, 0xec, 0xd8, 0xb0, 0xe0, 0xf0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x60, 0xff, 0x60, 0x3f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0xfc, 0x06, 0xff, 0x06, 0xfc, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x6a, 0xff, 0x65, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0xa6, 0xff, 0x56, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x3c, 0x18, 0x3c, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x3c, 0x18, 0x3c, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xd5, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0x66, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x06, 0xab, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x00, 0x18, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0xb0, 0xff, 0xb0, 0x98, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x19, 0x0d, 0xff, 0x0d, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x3f, 0x41, 0x81, 0x41, 0x3f, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0xfc, 0x82, 0x81, 0x82, 0xfc, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0x44, 0x44, 0x44, 0x44, 0x44, 0xc6, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x7c, 0x00, 0x7c, 0x44, 0x7c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x44, 0xc6, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x7c, 0xc6, 0x44, 0x44, 0x44, 0xc6, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x54, 0xd6, 0x54, 0x54, 0x54, 0xd6, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x28, 0x54, 0xee, 0x44, 0xc6, 0x44, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x28, 0x54, 0xee, 0x44, 0xc6, 0x44, 0x44, 0xc6, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe8, 0xbc, 0x82, 0x81, 0x82, 0xbc, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x80, 0xbc, 0xb8, 0xac, 0x86, 0x83, 0x81, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x01, 0x81, 0xc1, 0x61, 0x35, 0x1d, 0x3d, 0x01, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0xc6, 0x44, 0x44, 0x44, 0xc6, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0xfe, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x60, 0x60, 0x60, 0x66, 0x3c, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x06, 0x06, 0x3e, 0x66, 0xc6, 0xc6, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x7e, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0xfe, 0x16, 0x16, 0x16, 0x7e, 0x16, 0x26, 0x26, 0x26, 0xfe, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x3e, 0x66, 0xcf, 0xdb, 0xdb, 0xf3, 0x66, 0x7c, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x3e, 0x60, 0xc0, 0xc0, 0xfe, 0xc0, 0xc0, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x3e, 0x64, 0xc8, 0xc8, 0xfe, 0xc8, 0xd0, 0x70, 0x3e, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x3e, 0x60, 0xc0, 0xfe, 0xc0, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf8, 0x0c, 0x06, 0x06, 0xfe, 0x06, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xf8, 0x1c, 0x16, 0x26, 0xfe, 0x26, 0x26, 0x4c, 0xf8, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xf8, 0x0c, 0x06, 0xfe, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xe7, 0x00, 0x00},
{0x00, 0x00, 0xe7, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xc1, 0x60, 0x30, 0x18, 0x0c, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xff, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0xc0, 0xc0, 0x00, 0x00, 0x00},
{0x00, 0xc0, 0xc0, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x18, 0x7e, 0x18, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x06, 0x06, 0x06, 0x0c, 0xcc, 0x6c, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe3, 0x33, 0x66, 0x36, 0xe6, 0x0c, 0xcc, 0x6c, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x33, 0x73, 0xb6, 0xf6, 0x36, 0x0c, 0xcc, 0x6c, 0x38, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xd8, 0xd8, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdb, 0xdb, 0x6e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x16, 0x0c, 0x1c, 0x34, 0x62, 0xff, 0x02, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x1a, 0x1c, 0x38, 0x58, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6c, 0x6c, 0x6c, 0x6e, 0x7c, 0xec, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x33, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00},
{0x2a, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0xa8, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x3c, 0x5a, 0x99, 0x99, 0x5a, 0x3c, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x33, 0x66, 0x66, 0x66, 0x7e, 0xe7, 0xe7, 0xe7, 0xe7, 0x7e, 0x66, 0x66, 0x66, 0xcc, 0x00, 0x00},
{0x2a, 0x54, 0x54, 0x54, 0x7c, 0xd6, 0xd6, 0xd6, 0xd6, 0x7c, 0x54, 0x54, 0x54, 0xa8, 0x00, 0x00},
{0x18, 0x34, 0x30, 0x30, 0x38, 0x35, 0x33, 0x37, 0x30, 0x30, 0x30, 0x30, 0xb0, 0x60, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x3c, 0x5a, 0xfa, 0x5a, 0x5a, 0x3c, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x0c, 0x1a, 0x18, 0x18, 0x3c, 0x5a, 0x5f, 0x5a, 0x5a, 0x3c, 0x18, 0x18, 0x58, 0x30, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0xfc, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x00, 0x7e, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x76, 0xdc, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0xdb, 0xdb, 0x4e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0xdb, 0xdb, 0x1b, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x1c, 0x30, 0x30, 0x30, 0x18, 0x0c, 0x0c, 0x0c, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x10, 0x76, 0xdc, 0x10, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x76, 0xdc, 0x10, 0xfe, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x08, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x08, 0x76, 0xdc, 0x10, 0xfe, 0x20, 0xfe, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x76, 0xdc, 0x10, 0x76, 0xdc, 0x20, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x7c, 0x00, 0x7c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x66, 0x00, 0x00, 0x66, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x66, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x60, 0x60, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x06, 0x00, 0x7e, 0x00, 0x00, 0x7e, 0x00, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0xdf, 0x00, 0x00, 0xdf, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0xfb, 0x00, 0x00, 0xfb, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x28, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x10, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x44, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x44, 0x28, 0x10, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x10, 0x7c, 0x28, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x10, 0x28, 0x44, 0x7c, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x26, 0x7c, 0xb4, 0x6c, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x68, 0x54, 0x54, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x08, 0x10, 0x00, 0x10, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x08, 0x7e, 0x08, 0x10, 0x7e, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x08, 0xfe, 0x08, 0x10, 0xfe, 0x10, 0x20, 0xfe, 0x20, 0x40, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x08, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x08, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x1b, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x1b, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36, 0x1b, 0x36, 0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x66, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x66, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0xce, 0x7c, 0x10, 0x7c, 0xe6, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0xe0, 0x38, 0x2e, 0x38, 0xe0, 0x40, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0xe0, 0x38, 0x2e, 0x38, 0xe0, 0x40, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x0e, 0x38, 0xe8, 0x38, 0x0e, 0x10, 0x76, 0xdc, 0x20, 0x20, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0xe0, 0x38, 0x2e, 0x38, 0xe0, 0x40, 0x76, 0xdc, 0x80, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x0e, 0x38, 0xe8, 0x38, 0x1e, 0xf0, 0x38, 0x2e, 0x38, 0xe0, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x08, 0xe8, 0x38, 0x0e, 0x38, 0xf0, 0x1e, 0x38, 0xe0, 0x38, 0x2e, 0x20, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0xf2, 0x1c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x9e, 0x70, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x06, 0x0c, 0x38, 0xe8, 0x38, 0x1c, 0x16, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0xd0, 0x70, 0x38, 0x2e, 0x38, 0x60, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x7e, 0xc8, 0xc8, 0xd0, 0xd0, 0x7e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0xfc, 0x16, 0x16, 0x26, 0x26, 0xfc, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0x7e, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x7e, 0xc8, 0xc8, 0xd0, 0xd0, 0x7e, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xfc, 0x16, 0x16, 0x26, 0x26, 0xfc, 0x40, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7e, 0xc0, 0xc0, 0xc0, 0xc0, 0x7e, 0x08, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfc, 0x06, 0x06, 0x06, 0x06, 0xfc, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x92, 0xa2, 0xfa, 0xa2, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x82, 0x92, 0xba, 0xba, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x82, 0x92, 0xba, 0x92, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x54, 0x92, 0xfe, 0x92, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0xfe, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0xaa, 0x92, 0xaa, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x8a, 0x92, 0xa2, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x92, 0xba, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x92, 0xaa, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x54, 0xd6, 0xba, 0xd6, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0xba, 0x82, 0xba, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0xba, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x92, 0x92, 0xfe, 0x92, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0xfe, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xaa, 0x92, 0xaa, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x92, 0xba, 0x92, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xff, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x03, 0x03, 0x03, 0x03, 0xff, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0x60, 0x60, 0x7e, 0x60, 0x7e, 0x60, 0x60, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xff, 0xc0, 0xff, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xd8, 0xdf, 0xd8, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xa8, 0xa8, 0xa8, 0xa8, 0xaf, 0xa8, 0xa8, 0xa8, 0xa8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd8, 0xd8, 0xdf, 0xd8, 0xdf, 0xd8, 0xd8, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc2, 0xc4, 0xc4, 0xff, 0xc8, 0xc8, 0xd0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xc4, 0xc4, 0xff, 0xc8, 0xff, 0xd0, 0xd0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd9, 0xda, 0xda, 0xdf, 0xda, 0xda, 0xdc, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xd8, 0xd9, 0xda, 0xdf, 0xda, 0xdf, 0xda, 0xdc, 0xd8, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x0c, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x60, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x06, 0x1e, 0x76, 0xc6, 0x76, 0x1e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc0, 0xf0, 0xdc, 0xc6, 0xdc, 0xf0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x1e, 0x76, 0xc6, 0x76, 0x1e, 0x06, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xf0, 0xdc, 0xc6, 0xdc, 0xf0, 0xc0, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xbf, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0xfd, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x7d, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x00, 0xc6, 0x00, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xf0, 0xc8, 0xc4, 0xc4, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x03, 0x07, 0x0b, 0x13, 0x23, 0x43, 0x83, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x38, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x92, 0x44, 0x28, 0x92, 0x28, 0x44, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0xc6, 0xaa, 0x92, 0xaa, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0xc4, 0xa8, 0x90, 0xa8, 0xc4, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x82, 0x46, 0x2a, 0x12, 0x2a, 0x46, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x80, 0x40, 0x20, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x08, 0x10, 0x28, 0x44, 0x82, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x38, 0x38, 0x6c, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc6, 0x6c, 0x6c, 0x38, 0x38, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x3e, 0x60, 0xce, 0xd8, 0xd8, 0xce, 0x60, 0x3e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xf8, 0x0c, 0xe6, 0x36, 0x36, 0xe6, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x44, 0x92, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0x92, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x10, 0x38, 0x54, 0x92, 0x92, 0x92, 0x92, 0x92, 0x92, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x64, 0xce, 0x64, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x4c, 0xe6, 0x4c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x15, 0x2a, 0x54, 0xa8, 0x54, 0x2a, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xa8, 0x54, 0x2a, 0x15, 0x2a, 0x54, 0xa8, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0xfe, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x00},
{0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0xfe, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf2, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x9e, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x0e, 0x1c, 0xf0, 0x1c, 0x16, 0xf2, 0x1c, 0x26, 0x22, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x88, 0xc8, 0x70, 0x1e, 0x70, 0xd0, 0x9e, 0x70, 0xe0, 0xa0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0xfe, 0xc8, 0xc8, 0xd0, 0xd0, 0xfe, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xfe, 0x16, 0x16, 0x26, 0x26, 0xfe, 0x40, 0xfe, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x08, 0xfe, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0xfe, 0x10, 0xfe, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0e, 0x38, 0xe0, 0x38, 0x0e, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xe0, 0x38, 0x0e, 0x38, 0xe0, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x02, 0x06, 0x1c, 0xf0, 0x1c, 0x06, 0x02, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x80, 0xc0, 0x70, 0x1e, 0x70, 0xc0, 0x80, 0x10, 0x76, 0xdc, 0x10, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x0e, 0x1e, 0x76, 0xd6, 0x76, 0x1e, 0x26, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0xc8, 0xf0, 0xdc, 0xd6, 0xdc, 0xf0, 0xe0, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x0e, 0x1e, 0x76, 0xd6, 0x76, 0x1e, 0x26, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0xc8, 0xf0, 0xdc, 0xd6, 0xdc, 0xf0, 0xe0, 0x20, 0xfe, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x3d, 0x66, 0xc7, 0xcb, 0xd3, 0xe3, 0x66, 0xbc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x78, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x42, 0xa5, 0x7e, 0x24, 0x24, 0x7e, 0xa5, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x38, 0x54, 0x8a, 0xf6, 0x82, 0x54, 0x38, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0xfe, 0xfe, 0x44, 0x44, 0x28, 0x10, 0x28, 0x44, 0x44, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x00, 0x00},
{0x60, 0x60, 0x30, 0x30, 0x18, 0x18, 0x0c, 0x0c, 0x18, 0x18, 0x30, 0x30, 0x60, 0x60, 0x00, 0x00},
{0x00, 0x03, 0x06, 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x06, 0x03, 0x00, 0x00},
{0x00, 0xc0, 0x60, 0x30, 0x30, 0x18, 0x18, 0x18, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x18, 0x18, 0x30, 0x30, 0x60, 0xc0, 0x00, 0x00},
{0x00, 0x3f, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30},
{0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x3f, 0x00, 0x00},
{0x00, 0xfc, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c},
{0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0xfc, 0x00, 0x00},
{0x00, 0x07, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xe0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x07, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0xe0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x07, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xe0, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x07, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0xe0},
{0xe0, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x07},
{0x00, 0x00, 0xff, 0xc1, 0xc0, 0x60, 0x60, 0x60, 0x60, 0x30, 0x30, 0x30, 0x30, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x30, 0x30, 0x30, 0x30, 0x60, 0x60, 0x60, 0x60, 0xc0, 0xc1, 0xff, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xff, 0x00, 0xff, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0x78, 0x78, 0x38, 0x38, 0x18, 0x18, 0x00, 0x00},
{0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03},
{0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x07, 0x05, 0x05, 0x05, 0x05, 0x25, 0x79, 0xc2, 0x7c, 0x20, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xf8, 0xd8, 0xd8, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xf0, 0x0f, 0x0c, 0x0e, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd8, 0xd8, 0xf8, 0x70, 0x20, 0x0f, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xf0, 0xc0, 0xe0, 0xc0, 0xc0, 0x0f, 0x0c, 0x0e, 0x0c, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0xc0, 0xc0, 0xc0, 0x70, 0x1e, 0x1b, 0x1e, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x98, 0xd8, 0xf8, 0xd8, 0xd8, 0x0c, 0x0c, 0x0c, 0x0c, 0x0f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7c, 0xfe, 0xc6, 0xc6, 0x60, 0x30, 0x30, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x6d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00},
{0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1f, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0xfc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xfc, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xfc, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xfc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xfc, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0x1f, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0xff, 0xff, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0e, 0x0c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x70, 0x30, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x30, 0x70, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x0c, 0x0e, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80},
{0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01},
{0x81, 0x81, 0x42, 0x42, 0x24, 0x24, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x42, 0x42, 0x81, 0x81},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18},
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe},
{0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc},
{0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8},
{0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0},
{0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0},
{0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0},
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80},
{0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f},
{0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44},
{0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa},
{0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77},
{0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
{0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x7c, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0xba, 0xba, 0xba, 0xba, 0xba, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0xfe, 0x82, 0xfe, 0x82, 0xfe, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xaa, 0xfe, 0xaa, 0xfe, 0xaa, 0xfe, 0xaa, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x8a, 0xc6, 0xa2, 0x92, 0x8a, 0xc6, 0xa2, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xa2, 0xc6, 0x8a, 0x92, 0xa2, 0xc6, 0x8a, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0xaa, 0xc6, 0xaa, 0x92, 0xaa, 0xc6, 0xaa, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x44, 0x44, 0x44, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0xfc, 0xfc, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x42, 0x42, 0x84, 0x84, 0xfc, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x44, 0x44, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x80, 0xc0, 0xa0, 0x90, 0x88, 0x84, 0x88, 0x90, 0xa0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x70, 0x78, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x70, 0x48, 0x70, 0x40, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf8, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0x98, 0x86, 0x98, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0x82, 0x44, 0x44, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x06, 0x0e, 0x1e, 0x3e, 0x7e, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x06, 0x0a, 0x12, 0x22, 0x42, 0x22, 0x12, 0x0a, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x38, 0x78, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x38, 0x48, 0x38, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x3e, 0xfe, 0x3e, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x02, 0x0e, 0x32, 0xc2, 0x32, 0x0e, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x7c, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0x44, 0x82, 0x82, 0x44, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x44, 0x54, 0xba, 0xba, 0x54, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x99, 0xbd, 0xbd, 0xbd, 0xbd, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x28, 0x28, 0x44, 0x82, 0x82, 0x44, 0x28, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x14, 0x40, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x02, 0x28, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0xa5, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x99, 0xa5, 0xa5, 0xa5, 0xa5, 0x99, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x72, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0x72, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4e, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x4e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x7e, 0xff, 0xff, 0xff, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4e, 0x8f, 0x8f, 0x8f, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4e, 0x8f, 0x8f, 0x8f, 0xff, 0xff, 0xff, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x70, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0x70, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x0e, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0e, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
{0xff, 0xff, 0xc3, 0xbd, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0xbd, 0xc3, 0xff, 0xff, 0xff, 0xff},
{0xff, 0xff, 0xc3, 0xbd, 0x7e, 0x7e, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x7e, 0x7e, 0xbd, 0xc3, 0xff, 0xff, 0xff, 0xff},
{0x00, 0x00, 0x30, 0x40, 0x80, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0c, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x30, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x01, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x0f, 0x1f, 0x1f, 0x3f, 0x3f, 0x7f, 0x7f, 0xff, 0xff},
{0x80, 0x80, 0xc0, 0xc0, 0xe0, 0xe0, 0xf0, 0xf0, 0xf8, 0xf8, 0xfc, 0xfc, 0xfe, 0xfe, 0xff, 0xff},
{0xff, 0xff, 0xfe, 0xfe, 0xfc, 0xfc, 0xf8, 0xf8, 0xf0, 0xf0, 0xe0, 0xe0, 0xc0, 0xc0, 0x80, 0x80},
{0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x3f, 0x1f, 0x1f, 0x0f, 0x0f, 0x07, 0x07, 0x03, 0x03, 0x01, 0x01},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0xff, 0xfd, 0xf9, 0xf1, 0xf1, 0xe1, 0xc1, 0x81, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x81, 0x83, 0x87, 0x8f, 0x8f, 0x9f, 0xbf, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xff, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0x99, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x28, 0x28, 0x44, 0x44, 0x92, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x74, 0x74, 0xf2, 0xf2, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0x38, 0x5c, 0x5c, 0x9e, 0x9e, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x92, 0x92, 0x92, 0xf2, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0xf2, 0x92, 0x92, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x9e, 0x92, 0x92, 0x92, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xfe, 0x92, 0x92, 0x92, 0x9e, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x4a, 0x89, 0x89, 0x89, 0xf9, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0xf9, 0x89, 0x89, 0x89, 0x4a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x81, 0x9f, 0x91, 0x91, 0x91, 0x52, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x52, 0x91, 0x91, 0x91, 0x9f, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x54, 0x38, 0xfe, 0x38, 0x54, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x30, 0x7c, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x7c, 0xfe, 0x10, 0x10, 0x10, 0x10, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x38, 0xfe, 0x7c, 0x38, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x28, 0xee, 0x44, 0x54, 0x6c, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x18, 0x30, 0x60, 0xc0, 0x60, 0x34, 0x1c, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xc6, 0xcc, 0xd8, 0xf0, 0xd8, 0xcd, 0xc7, 0xcf, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x82, 0x92, 0x82, 0x44, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x42, 0x42, 0xa5, 0xa5, 0x42, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x42, 0xa5, 0xa5, 0x42, 0x42, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0c, 0x78, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x36, 0x36, 0x1c, 0x18, 0x30, 0x70, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x82, 0x82, 0x82, 0x82, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0x86, 0x8a, 0xba, 0x92, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0xfe, 0x82, 0xee, 0xba, 0xba, 0xee, 0x82, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x82, 0xc6, 0x6c, 0x7c, 0x38, 0x7c, 0x6c, 0xc6, 0x82, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x7c, 0x82, 0xaa, 0x82, 0x44, 0x7c, 0x44, 0x38, 0x00, 0x44, 0xc6, 0x38, 0xc6, 0x44, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x44, 0xee, 0xfe, 0x92, 0xba, 0x7c, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x7e, 0x18, 0x18, 0xff, 0x18, 0x1e, 0x78, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x7e, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x38, 0x10, 0x10, 0x92, 0xfe, 0x92, 0x10, 0x10, 0x38, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x72, 0xe0, 0xc4, 0xdf, 0xce, 0xca, 0xe0, 0x72, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x54, 0x28, 0x54, 0xaa, 0xaa, 0xaa, 0xaa, 0x54, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x5a, 0x99, 0x99, 0x99, 0xbd, 0xff, 0xdb, 0x5a, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x42, 0x81, 0x85, 0xb1, 0xf9, 0xff, 0xdf, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xfe, 0xfe, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0xee, 0xee, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0x81, 0x99, 0xa5, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xa5, 0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xff, 0xdb, 0xff, 0xff, 0xdb, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x54, 0x28, 0xc6, 0x28, 0x54, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x78, 0x14, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x14, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x28, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x28, 0x1e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x7e, 0x18, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x06, 0x0e, 0x1a, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x03, 0x03, 0x7b, 0xcf, 0xcf, 0xcf, 0x0f, 0x1b, 0x33, 0xff, 0x03, 0x03, 0x03, 0x00, 0x00},
{0x00, 0x00, 0x60, 0xf0, 0x60, 0x6e, 0x73, 0x63, 0x63, 0x66, 0x66, 0x63, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xd6, 0x54, 0x54, 0x7c, 0x54, 0x54, 0xd6, 0x38, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x3c, 0xdb, 0xdb, 0xdb, 0xdb, 0x7e, 0x3c, 0x18, 0x3c, 0x18, 0x18, 0x00, 0x00},
{0x00, 0x00, 0xf8, 0xcc, 0xcc, 0xcc, 0xcc, 0xf8, 0xc0, 0xc0, 0xc0, 0xc0, 0xfe, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x42, 0xa5, 0xa5, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0xc3, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0x7e, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x7e, 0xc3, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7e, 0xdb, 0xd8, 0x70, 0x00, 0x00, 0x0e, 0x1b, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1e, 0x33, 0x33, 0x33, 0x33, 0x1b, 0x7b, 0xdb, 0xdb, 0x73, 0x03, 0x01, 0x00, 0x00},
{0x00, 0x00, 0x94, 0x7c, 0x55, 0x57, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x06, 0x0b, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x24, 0xe7, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x94, 0x7c, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x54, 0x04, 0x03, 0x00, 0x00},
{0x00, 0x00, 0x1f, 0x07, 0x8f, 0xdb, 0x73, 0x70, 0xd8, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x90, 0x50, 0x70, 0x68, 0x48, 0x48, 0x4e, 0x49, 0x09, 0x0e, 0x10, 0x20, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x2a, 0x7e, 0xaa, 0x00, 0x00, 0x2a, 0x7e, 0xaa, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc3, 0x66, 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66, 0xc3, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x6c, 0x92, 0x82, 0x82, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x44, 0x82, 0x44, 0x28, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x24, 0x42, 0x81, 0x81, 0x66, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x18, 0x24, 0x3c, 0xe7, 0xa5, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x38, 0x78, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x30, 0x3c, 0x3e, 0x32, 0x30, 0x30, 0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x7f, 0x6f, 0x63, 0x63, 0x63, 0x63, 0xe3, 0xe7, 0xc7, 0x06, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x7f, 0x63, 0x7f, 0x63, 0x63, 0x63, 0x63, 0x63, 0xe7, 0xe7, 0xc6, 0x00, 0x00, 0x00},
{0x00, 0x00, 0xc0, 0xc0, 0xc0, 0xc0, 0xcc, 0xde, 0xe6, 0xc4, 0xd8, 0xe0, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x40, 0x40, 0x44, 0x5c, 0x74, 0x44, 0x44, 0x5c, 0x74, 0x44, 0x04, 0x04, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x04, 0x46, 0x5c, 0x74, 0xc4, 0x46, 0x5c, 0x74, 0xc4, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x3b, 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3c, 0x6e, 0x66, 0x60, 0xfe, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x3e, 0x6e, 0x66, 0x66, 0xfe, 0x66, 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6e, 0xdb, 0xdb, 0xd8, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x6f, 0xdb, 0xdb, 0xdb, 0xff, 0xdb, 0xdb, 0xdb, 0xdb, 0xff, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x38, 0x6c, 0x6c, 0x6f, 0x6c, 0x6c, 0x6c, 0x6c, 0x6d, 0xf6, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x29, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x29, 0x5e, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x89, 0x86, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0a, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0a, 0x00, 0x0a, 0x00, 0x06, 0x49, 0x89, 0x86, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x14, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x88, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x88, 0x80, 0x88, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x94, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x94, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x0a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x88, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x94, 0x80, 0x88, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x0a, 0x00, 0x04, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x14, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x94, 0x80, 0x94, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x94, 0x80, 0x94, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x0a, 0x00, 0x0a, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x14, 0x00, 0x14, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x28, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x28, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x28, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x28, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x38, 0x28, 0x70, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x00, 0x14, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x01, 0x02, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00},
{0x04, 0x09, 0x12, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x46, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0xa4, 0x09, 0x12, 0x04, 0x08, 0x44, 0x82, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa4, 0x09, 0x12, 0x04, 0x08, 0x48, 0x84, 0x82, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa2, 0x0c, 0x13, 0x0c, 0x10, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xa2, 0x0c, 0x13, 0x0c, 0x10, 0x10, 0x08, 0x04, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x41, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x00, 0x01, 0x41, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x1c, 0x14, 0x38, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x38, 0x40, 0x38, 0x40, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x70, 0x80, 0x70, 0x80, 0x10, 0x68, 0x88, 0x74, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf0, 0x10, 0x14, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xf7, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0x3d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0x3d, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x38, 0x4c, 0x52, 0x32, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x18, 0x20, 0x3f, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x70, 0x80, 0x70, 0x80, 0x08, 0x14, 0x60, 0x80, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x1c, 0x20, 0x1c, 0x20, 0x00, 0x00, 0x07, 0x18, 0x20, 0x3f, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x29, 0x01, 0x19, 0x21, 0x19, 0xa1, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x00, 0x2a, 0x02, 0x32, 0x42, 0x32, 0xc6, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x00, 0xa3, 0x0c, 0x10, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x40, 0x00, 0xa3, 0x0c, 0x10, 0x10, 0x08, 0x04, 0xfb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x18, 0x10, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x18, 0x10, 0x20, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x08, 0x08, 0x08, 0x08, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x23, 0x54, 0x33, 0x24, 0x40, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x3c, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x08, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x3c, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x14, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x10, 0x00, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x10, 0x00, 0x10},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x82, 0x7c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x20, 0x20, 0x20, 0x20, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x98, 0x60, 0xc2, 0x12, 0x92, 0x9c, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x92, 0x9c, 0x60, 0x0e, 0x70, 0x0e, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x60, 0x04, 0x54, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x10, 0x60, 0x04, 0x54, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x04, 0x54, 0x58, 0x20, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x04, 0x54, 0x58, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x0e, 0xf0, 0x02, 0x92, 0x9c, 0x60, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x18, 0x60, 0x02, 0x92, 0x9c, 0x60, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x12, 0x9c, 0x60, 0x0e, 0x70, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x10, 0x28, 0x50, 0x28, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x14, 0x28, 0x14, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x08, 0x10, 0x54, 0x38, 0x54, 0x10, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x10, 0x08, 0x2a, 0x1c, 0x2a, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x2a, 0x14, 0x00, 0x21, 0x69, 0xa9, 0x69, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x08, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x10, 0x10, 0x10, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x08, 0x08, 0x08, 0x08, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x10, 0x20, 0x10, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x04, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x10, 0x10, 0x10, 0x10, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x08, 0x08, 0x08, 0x08, 0x08, 0x18, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x7c, 0x28, 0x7c, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x28, 0x28, 0x10, 0x2a, 0x24, 0x1a, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x38, 0x38, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x20, 0x10, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x08, 0x10, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x10, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x54, 0x30, 0x18, 0x54, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x08, 0x08, 0x10, 0x10, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x44, 0x54, 0x58, 0x40, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x06, 0x18, 0x60, 0x06, 0x18, 0x60, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x12, 0xca, 0x2c, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x0c, 0x30, 0x00, 0x00},
{0x0c, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x06, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x08, 0x14, 0x0c, 0x08, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x14, 0x18, 0x60, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x06, 0x18, 0x60, 0x00, 0x00},
{0x0a, 0x2a, 0x2c, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x12, 0x92, 0x9c, 0x60, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x24, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x20, 0x1e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x02, 0x3c, 0x40, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x01, 0x3e, 0x40, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x18, 0x20, 0x1c, 0x20, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x0c, 0x10, 0x0e, 0x10, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x00, 0x0c, 0x10, 0x0e, 0x10, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x00, 0x0c, 0x10, 0x0e, 0x10, 0x00, 0x00},
{0x00, 0x30, 0x40, 0x38, 0x40, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x30, 0x40, 0x38, 0x40, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x1c, 0x20, 0x1c, 0x20, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x28, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x50, 0x00, 0x10, 0x10, 0x68, 0x88, 0x74, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x14, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x40, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x40, 0x80, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x88, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x88, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x80, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x20, 0x00, 0x00, 0x70, 0x8f, 0x30, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x00, 0x00, 0x70, 0x8f, 0x32, 0x41, 0x80, 0x80, 0x80, 0x40, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x00, 0x38, 0x47, 0x18, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x00, 0x70, 0x8f, 0x32, 0xc1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x08, 0x04, 0x02, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x08, 0x08, 0x04, 0x46, 0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x02, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x07, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x15, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2a, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x14, 0x00, 0x01, 0x15, 0x88, 0x84, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x04, 0x00, 0x0a, 0x00, 0x00, 0x01, 0x15, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x14, 0x00, 0x00, 0x00, 0x2a, 0xd5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x04, 0x00, 0x06, 0x09, 0x31, 0x9e, 0x88, 0x88, 0x70, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x00, 0x06, 0x29, 0x31, 0xde, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x20, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0xa2, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x24, 0x20, 0x20, 0x2c, 0x32, 0x22, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0x22, 0x41, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x10, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x40, 0x00, 0x00, 0x70, 0x80, 0x8c, 0x70, 0x40, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x08, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0x22, 0x41, 0x80, 0x80, 0x80, 0x41, 0x3e, 0x00, 0x00},
{0x00, 0x00, 0x10, 0x00, 0x00, 0x0e, 0x10, 0x10, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x1e, 0x22, 0x1c, 0xe3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x85, 0x83, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x04, 0x00, 0x06, 0x49, 0x89, 0x86, 0x7d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x00, 0x06, 0x09, 0x09, 0x47, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x0a, 0x00, 0x00, 0x06, 0x09, 0x49, 0x87, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x0a, 0x06, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x14, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x0c, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x19, 0x21, 0x19, 0x21, 0x01, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x32, 0x42, 0x32, 0x42, 0x02, 0x86, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x10, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x06, 0x18, 0x20, 0x20, 0x10, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x42, 0x82, 0x82, 0x84, 0x78, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x12, 0x3c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x3c, 0x4b, 0x4a, 0x44, 0x40, 0x40, 0x40, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x32, 0xcc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x32, 0xcd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x08, 0x00, 0x00, 0x41, 0x81, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x01, 0x41, 0x81, 0x81, 0x42, 0x3c, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x18, 0x24, 0x22, 0x22, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x10, 0x10, 0x68, 0x88, 0x74, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x40, 0x30, 0x4e, 0x49, 0x39, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x08, 0x14, 0x24, 0x28, 0xf3, 0x24, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0e, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x12, 0x0f, 0x02, 0x04, 0x18, 0x60, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x08, 0x88, 0x86, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x24, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x88, 0x87, 0x81, 0x7e, 0x00, 0x24, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x04, 0xf8, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x08, 0xf7, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00},
{0x68, 0x90, 0x02, 0x22, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x68, 0x90, 0x02, 0x32, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x60, 0x80, 0x72, 0xa2, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x30, 0x40, 0x3a, 0x52, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x42, 0x22, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x18, 0x20, 0x1c, 0x20, 0x00},
{0x00, 0x00, 0x22, 0x12, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x18, 0x20, 0x1c, 0x20, 0x00},
{0x00, 0x00, 0x42, 0x22, 0x12, 0x0a, 0x04, 0x0c, 0x12, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0x00, 0x00, 0x22, 0x12, 0x12, 0x0a, 0x0a, 0x0e, 0x3d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
{0xf1, 0x35, 0x55, 0x8a, 0xe0, 0x06, 0x95, 0xd6, 0xb5, 0x97, 0x00, 0xee, 0x8a, 0xee, 0x28, 0xe8},
{0x00, 0x38, 0x7c, 0x7c, 0xc6, 0x92, 0xf2, 0xe6, 0xfe, 0xe6, 0x7c, 0x7c, 0x38, 0x00, 0x00, 0x00},
/* Special glyph for unknown character */
{0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00}
};
 
/** @}
/branches/arm/kernel/genarch/src/fb/logo-196x66.c
0,0 → 1,13110
/*
* Copyright (c) 2008 Martin Decky
* 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 genarch
* @{
*/
/** @file
*/
 
#include <genarch/fb/logo-196x66.h>
 
uint32_t fb_logo[LOGO_WIDTH * LOGO_HEIGHT] = {
 
/* Scanline 0 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 1 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 2 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 3 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xf9f9f8,
0xf5f3f1,
0xf3f1ee,
0xf3f2ef,
0xf7f7f6,
0xfbfbfb,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 4 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefd,
0xf9f9f8,
0xf3f1ed,
0xeeeae4,
0xece8df,
0xebe6de,
0xeae5dd,
0xeae5dd,
0xeae5de,
0xeae8e4,
0xf1f1f0,
0xfbfbfb,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 5 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefd,
0xf9f9f8,
0xf4f2ef,
0xefebe5,
0xf0ece5,
0xeeeae4,
0xe3e0db,
0xdfdcd8,
0xe2e0db,
0xeeebe6,
0xeeebe5,
0xeae5dd,
0xe8e4db,
0xe5e1db,
0xe9e9e8,
0xfafafa,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 6 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefd,
0xfaf9f9,
0xf4f3ef,
0xefece6,
0xf0ece5,
0xeeebe5,
0xdfdcd7,
0xc6c4bd,
0xbebcb5,
0xcfcdc8,
0xd3d2cd,
0xd1cfca,
0xc0beb7,
0xcccac3,
0xeae7e3,
0xe9e5dd,
0xe7e3da,
0xdedbd8,
0xe8e8e7,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 7 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfafafa,
0xf5f4f0,
0xf1eee8,
0xf0ece4,
0xf0ede7,
0xe1ded9,
0xc9c7c1,
0xbebcb4,
0xd1cfca,
0xecebe8,
0xf9f9f7,
0xfaf9f7,
0xf8f6f4,
0xf7f5f2,
0xf4f3f1,
0xdcdad6,
0xc2c0b9,
0xe6e4de,
0xe5e2dc,
0xe2ddd8,
0xd7d5d4,
0xf2f2f1,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 8 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfbfbfb,
0xf6f5f2,
0xf1eee9,
0xf1ede5,
0xf1ede6,
0xe4e1db,
0xcecbc4,
0xbebcb5,
0xcfcdc8,
0xe7e6e4,
0xf8f8f6,
0xfafaf8,
0xf9f7f5,
0xf7f5f2,
0xf5f3f0,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xd9d7d2,
0xc8c5bf,
0xe9e5e0,
0xe4dfd8,
0xd5d2ce,
0xe1e1e1,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 9 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfbfbfb,
0xf7f6f3,
0xf2efea,
0xf1ede6,
0xf1eee7,
0xe5e3de,
0xd0cec7,
0xbfbdb5,
0xcdcbc5,
0xe4e3e0,
0xf7f7f6,
0xfbfaf9,
0xf9f8f6,
0xf8f6f3,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf1efeb,
0xc5c2bb,
0xe2dfdb,
0xe5e0da,
0xded9d3,
0xd3d2d1,
0xf4f4f4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 10 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfcfcfb,
0xf8f6f4,
0xf3f0eb,
0xf1eee7,
0xf2efe8,
0xe8e5df,
0xd3d1cb,
0xc0beb6,
0xcbc9c3,
0xe1e0dc,
0xf5f4f3,
0xfbfaf8,
0xfaf9f7,
0xf8f7f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ec,
0xf2efec,
0xdbd9d4,
0xcdcbc4,
0xe8e4de,
0xe3ded7,
0xd0cecb,
0xe7e7e6,
0xfdfdfc,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 11 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfcfcfb,
0xf8f7f4,
0xf4f1ed,
0xf2eee8,
0xf3efe9,
0xeae7e1,
0xd6d4cd,
0xc3c1b9,
0xcac8c2,
0xdddcd8,
0xf3f2f1,
0xfafaf8,
0xfbfaf7,
0xf9f7f5,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf1efeb,
0xf1eeeb,
0xece9e5,
0xc3c1ba,
0xe5e3de,
0xe3ded7,
0xd9d5d0,
0xd6d5d5,
0xf7f7f7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 12 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfcfcfc,
0xf9f8f5,
0xf5f2ee,
0xf3efe8,
0xf4f0e9,
0xece9e3,
0xd9d7d1,
0xc4c2bb,
0xc8c6c0,
0xd9d8d4,
0xf1f0ef,
0xfaf9f8,
0xfbfaf8,
0xfaf8f5,
0xf9f7f4,
0xf8f6f4,
0xf8f6f3,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xd2cfc9,
0xd3d2cc,
0xe4e0db,
0xded9d3,
0xcfccca,
0xededec,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 13 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xf9f9f7,
0xf5f3f0,
0xf3efe8,
0xf4f0e9,
0xeeeae5,
0xdddad4,
0xc7c4bd,
0xc7c6bf,
0xd7d6d1,
0xeeedeb,
0xf9f9f8,
0xfcfbfa,
0xfaf9f6,
0xf9f7f4,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf1efeb,
0xf1eeeb,
0xf1eeea,
0xf0ede9,
0xefece8,
0xefece8,
0xe4e2dd,
0xc4c2bb,
0xe5e2de,
0xdfdad3,
0xd3d0cb,
0xdbdbdb,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 14 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xfaf9f7,
0xf6f4f0,
0xf3f0e9,
0xf4f0ea,
0xefece6,
0xdfddd7,
0xcbc8c1,
0xc7c5be,
0xd4d3ce,
0xebebe8,
0xf8f8f6,
0xfcfcfa,
0xfbfaf7,
0xfaf9f6,
0xf9f7f5,
0xf9f7f4,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xefece8,
0xeeebe7,
0xedeae6,
0xc8c6bf,
0xdcdad5,
0xe1dcd6,
0xdbd7d0,
0xd0cfcd,
0xf1f0f0,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 15 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfafaf9,
0xf7f5f1,
0xf4f1ea,
0xf5f1ea,
0xf1ede7,
0xe2e0da,
0xcccac3,
0xc6c5be,
0xd1cfca,
0xe9e8e6,
0xf8f7f6,
0xfcfcfb,
0xfbfaf8,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xedeae5,
0xdedbd5,
0xc7c6bf,
0xe5e2dd,
0xded9d3,
0xcfcdc9,
0xe2e2e2,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 16 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xfbfbf9,
0xf6f3ed,
0xf4f1e9,
0xf4f1eb,
0xe7e4df,
0xcfcdc6,
0xc7c5be,
0xceccc7,
0xe6e5e2,
0xf7f6f5,
0xfdfcfb,
0xfcfbf9,
0xfaf9f7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xe0dedb,
0xb4b2b1,
0xb6b5b4,
0xe0dddb,
0xf1eeeb,
0xf1eeea,
0xf0ede9,
0xefece8,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xece9e5,
0xece9e4,
0xe8e6e1,
0xc3c1ba,
0xdfddd9,
0xddd9d3,
0xd6d3cd,
0xd3d2d1,
0xf5f5f4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 17 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfafaf9,
0xf4f0e8,
0xf5f1ea,
0xf3f1ed,
0xcbc9c3,
0xcac8c2,
0xe3e2df,
0xf5f4f3,
0xfdfcfb,
0xfdfbfa,
0xfcfaf8,
0xfbf9f7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xe1dedc,
0x7f7e7e,
0x706f6f,
0x757374,
0x8c8c8b,
0xe1dedb,
0xf0ede9,
0xefece8,
0xefece8,
0xeeebe7,
0xedeae6,
0xedeae5,
0xece9e4,
0xebe9e4,
0xeae8e3,
0xeae8e3,
0xd4d2cb,
0xcdcbc5,
0xe1ded8,
0xdad6cf,
0xcdcbc8,
0xe8e8e8,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 18 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfc,
0xf4f0eb,
0xf4f0e7,
0xf8f6f3,
0xc6c4bd,
0xdcdad7,
0xfbfbfa,
0xfdfcfb,
0xfcfaf8,
0xfcfaf8,
0xfbfaf7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f7f5,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf3f1ed,
0xb3b1af,
0x716f70,
0x7c7b7b,
0x898989,
0x8f8e8e,
0xbdbbba,
0xeeebe7,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xece9e5,
0xece9e4,
0xebe8e3,
0xeae8e3,
0xe9e7e2,
0xe8e6e1,
0xe2e0db,
0xc1bfb8,
0xe2dfdb,
0xdad7d0,
0xd2d0cb,
0xd7d7d7,
0xf8f8f7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 19 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf0f0ef,
0xf1ede4,
0xf8f6f0,
0xdbd9d4,
0xd3d2cd,
0xfdfcfb,
0xfcfbf9,
0xfcfaf8,
0xfcfaf8,
0xfbfaf7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f5,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xaeacab,
0x7a7979,
0x8f8e8e,
0xa3a2a2,
0xabaaab,
0xafaead,
0xe8e5e1,
0xeeebe7,
0xedeae6,
0xece9e4,
0xebe8e4,
0xeae8e3,
0xe9e7e2,
0xe9e7e2,
0xe8e6e1,
0xe7e5e0,
0xe7e4df,
0xcac8c1,
0xd4d2cc,
0xdcd9d3,
0xd6d3ce,
0xcdccca,
0xeeeeed,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 20 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefd,
0xe1e0dd,
0xf0ebe2,
0xfbfaf7,
0xc3c1ba,
0xf3f2f0,
0xfcfbf9,
0xfcfaf8,
0xfcfaf8,
0xfbf9f7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f4,
0xf7f5f2,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf3f1ee,
0xf2f0ec,
0xf2f0ec,
0xf1eeeb,
0xd5d3d1,
0x838282,
0x9d9c9c,
0xb4b3b3,
0xbdbcbd,
0xb6b5b5,
0xd7d4d1,
0xedeae6,
0xece9e5,
0xeae8e3,
0xeae8e3,
0xe9e7e2,
0xe9e7e2,
0xe7e5e0,
0xe7e4df,
0xe6e3de,
0xe5e2dd,
0xdbd8d3,
0xc3c0ba,
0xe1ded9,
0xd8d4ce,
0xcdcac6,
0xdedddd,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 21 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfc,
0xd2d1cd,
0xefeae1,
0xfcfaf8,
0xc3c1ba,
0xf9f8f7,
0xfcfaf8,
0xfcfaf8,
0xfbf9f7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f7f5,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf0eeeb,
0xebe9e6,
0xf3f1ee,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf1eeea,
0xefece9,
0x9c9b9a,
0xa1a0a0,
0xb9b7b8,
0xc2c0c1,
0xbfbdbe,
0xc2c1c0,
0xe9e6e2,
0xeae8e3,
0xe9e7e2,
0xe9e7e2,
0xe8e6e1,
0xe7e5e0,
0xe7e4df,
0xe6e3de,
0xe5e2dd,
0xe4e1dc,
0xe3dfda,
0xc4c1ba,
0xdbd9d4,
0xd8d5ce,
0xd4d0cb,
0xcfcecd,
0xf2f2f2,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xe3e3e3,
0xbbbbbb,
0x9d9d9d,
0x989898,
0xa4a4a4,
0xbfbfbf,
0xeaeaea,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf1f1f1,
0xc4c4c4,
0xa6a6a6,
0x989898,
0xa2a2a2,
0xc5c5c5,
0xf1f0f0,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 22 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfbfbfb,
0xb9b8b6,
0xeae5dd,
0xf9f6f3,
0xc4c2bb,
0xf2f2f0,
0xfbfaf7,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f5,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf6f4f1,
0xd2d0ce,
0x908f8e,
0x888686,
0xb3b1b0,
0xedebe8,
0xf3f1ee,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xc6c4c2,
0x9c9b9b,
0xb4b3b3,
0xc1bfc0,
0xc1c0c0,
0xbab9b9,
0xdeddd9,
0xe9e7e2,
0xe9e7e2,
0xe7e5e0,
0xe7e4df,
0xe7e4df,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe4e0db,
0xe3dfda,
0xd4d1cb,
0xc6c4bd,
0xdfdcd7,
0xd7d3cc,
0xcbc9c6,
0xe4e4e4,
0xfcfcfc,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xcbcbcb,
0x5f5f5f,
0x343434,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x363636,
0x737272,
0xdedede,
0xffffff,
0xffffff,
0xffffff,
0xf2f1f1,
0x8e8e8e,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x393939,
0x8a8a8a,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 23 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfbfbfb,
0xbbbbba,
0xc8c4bd,
0xf4f1eb,
0xd6d4cf,
0xdbd9d5,
0xfaf9f6,
0xfaf9f6,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f4,
0xf7f5f3,
0xf7f5f2,
0xf6f4f1,
0xe4e2df,
0x7f7e7e,
0x717071,
0x7a7878,
0x807f7f,
0xbbbab9,
0xf3f1ee,
0xf2f0ec,
0xf2f0ec,
0xf1eeeb,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xefece8,
0xe7e4e0,
0x999897,
0xacabab,
0xbebcbd,
0xc3c1c2,
0xbebcbd,
0xc9c8c7,
0xe7e5e0,
0xe7e5e0,
0xe7e4df,
0xe6e3de,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe3dfda,
0xe3dfda,
0xe2ded9,
0xdedad5,
0xc0beb6,
0xdedad5,
0xd6d2cb,
0xd1cec8,
0xd2d2d2,
0xf6f6f6,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb0afaf,
0x383838,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x414141,
0xc8c8c8,
0xffffff,
0xefefef,
0x626262,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x575656,
0xefefef,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 24 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfc,
0xd9d9d9,
0x9a9893,
0xede9e0,
0xefede8,
0xc3c1bb,
0xf7f6f3,
0xfaf9f6,
0xf9f8f5,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf5f3f0,
0xcac9c7,
0x717071,
0x7e7e7e,
0x908f8f,
0x9a9998,
0xa5a4a3,
0xebeae6,
0xf2efec,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xb5b3b1,
0xa2a1a1,
0xb8b7b7,
0xc2c0c1,
0xc1bfc0,
0xbcbaba,
0xe1dfda,
0xe7e4df,
0xe6e3de,
0xe5e1dc,
0xe4e0db,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xe1ddd8,
0xe1ddd8,
0xe0dbd6,
0xcbc8c1,
0xceccc7,
0xdad7d1,
0xd4d0ca,
0xcbc9c7,
0xeaeae9,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xd6d6d6,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x555555,
0xececec,
0x919191,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x7e7e7e,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 25 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xe9e9e9,
0x989694,
0xd8d4cc,
0xf5f3ed,
0xc8c6bf,
0xe8e6e2,
0xf9f7f5,
0xf9f7f4,
0xf8f6f4,
0xf8f6f4,
0xf8f6f4,
0xf7f5f3,
0xf7f5f2,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xd8d6d4,
0x7d7d7c,
0x8f8e8e,
0xa6a5a6,
0xb3b2b3,
0xb1b0b0,
0xd7d5d2,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xefece8,
0xefece8,
0xeeebe7,
0xedeae6,
0xedeae6,
0xece9e5,
0xd3d0cd,
0x999897,
0xb1afb0,
0xc0bebf,
0xc3c1c2,
0xbbbabb,
0xd2d0cc,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe3dfda,
0xe3dfda,
0xe2ded9,
0xe1ddd8,
0xe0dcd7,
0xe0dbd6,
0xdfdad5,
0xd9d5cf,
0xbfbdb6,
0xdedcd8,
0xd4d0ca,
0xcccac6,
0xd9d8d8,
0xf9f9f9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7a7a7a,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x494949,
0x666565,
0x3f3f3f,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x939392,
0x4e4e4e,
0x323232,
0x323232,
0x323232,
0x323232,
0x3f3f3f,
0x686868,
0x4c4c4c,
0x323232,
0x323232,
0x323232,
0x323232,
0x343434,
0xe8e7e7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 26 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf5f5f4,
0xbcbbba,
0xaaa7a2,
0xbebcb6,
0xa19f9c,
0xa5a4a1,
0xf4f2f0,
0xf8f6f4,
0xf8f6f4,
0xf8f6f3,
0xf7f5f2,
0xf7f5f2,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xedebe8,
0x9c9b9a,
0x999898,
0xb3b1b2,
0xc0bebf,
0xbebcbd,
0xc2c0c0,
0xefece9,
0xefece8,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xedeae6,
0xe4e1de,
0xc7c5c2,
0x9b9a99,
0x8d8c8c,
0xa9a8a8,
0xbdbbbb,
0xc3c1c2,
0xc0bebe,
0xc1bfbe,
0xe1ded9,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xe1ddd9,
0xe1ddd8,
0xe0dbd6,
0xe0dbd6,
0xdedad5,
0xdddad5,
0xdcd8d3,
0xc4c1bb,
0xd5d3ce,
0xd6d2cc,
0xd2cec9,
0xcbcac9,
0xefefef,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf6f6f6,
0x424242,
0x323232,
0x323232,
0x323232,
0x323232,
0x565656,
0xebebeb,
0xffffff,
0xd4d4d4,
0x414141,
0x323232,
0x323232,
0x323232,
0x323232,
0x414141,
0x343434,
0x323232,
0x323232,
0x323232,
0x434343,
0xe1e1e0,
0xffffff,
0xf1f1f1,
0x575757,
0x323232,
0x323232,
0x323232,
0x333333,
0xaeaeae,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 27 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfc,
0xe0e0e0,
0x8e8c89,
0x696865,
0x343434,
0x343434,
0xc8c7c7,
0xf8f6f4,
0xf7f5f3,
0xf7f5f2,
0xf6f4f1,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf4f2ef,
0xf3f1ee,
0xf3f1ed,
0xc4c2c1,
0x989797,
0xb3b1b2,
0xc1bfc0,
0xc2c0c1,
0xbcbabb,
0xe1dfdc,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xebe8e4,
0xdedbd8,
0xb0aeac,
0x828181,
0x6f6e6f,
0x797877,
0x8c8c8c,
0xa7a6a6,
0xbab9ba,
0xc3c1c2,
0xc2c0c1,
0xb9b8b8,
0xd7d4d0,
0xe3dfda,
0xe2deda,
0xe1ddd8,
0xe0dcd7,
0xe0dbd6,
0xdfdad5,
0xdedad5,
0xddd9d4,
0xdbd8d3,
0xdad7d2,
0xd2cfca,
0xc0beb7,
0xdddad6,
0xd4d0ca,
0xcbc8c5,
0xdfdfdf,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xdedede,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x323232,
0x929291,
0xffffff,
0xffffff,
0xfdfdfd,
0x616161,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x5c5c5c,
0xffffff,
0xffffff,
0xfefefe,
0x848484,
0x323232,
0x323232,
0x323232,
0x323232,
0x858585,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 28 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xefefef,
0xacaaaa,
0x83807c,
0x403f3f,
0x323232,
0x7d7c7c,
0xf4f2f0,
0xf7f5f2,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xe5e2e0,
0x9e9d9d,
0xacabab,
0xbebcbd,
0xc2c1c1,
0xbdbcbc,
0xcccac8,
0xedeae6,
0xe8e5e2,
0xcdcbc9,
0x9b9a98,
0x767575,
0x717070,
0x777676,
0x7e7e7d,
0x8b8a8a,
0x9c9b9b,
0xafaeae,
0xbdbcbc,
0xc3c1c2,
0xc3c1c2,
0xbebdbd,
0xc6c4c2,
0xe1ddd9,
0xe1dcd7,
0xe0dbd6,
0xe0dbd6,
0xdfdad5,
0xddd9d4,
0xddd9d4,
0xdbd8d3,
0xdad7d2,
0xd9d6d1,
0xd8d5cf,
0xc0bdb6,
0xdbd9d4,
0xd4d0ca,
0xd1cdc8,
0xcecdcc,
0xf3f3f3,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe0e0e0,
0xbfbfbf,
0xb4b4b4,
0xc0c0c0,
0xdfdfdf,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xebebeb,
0xc8c8c8,
0xb4b4b4,
0xbababa,
0xd5d4d4,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf1f1f1,
0xc7c7c7,
0xb4b4b4,
0xbfbfbf,
0xdddddd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x474747,
0xebebeb,
0xffffff,
0xffffff,
0xa3a3a3,
0x323232,
0x323232,
0x323232,
0x323232,
0x747474,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 29 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf9f9f9,
0xd0d0d0,
0x8c8a85,
0x595958,
0x333333,
0x414141,
0xe0dfdc,
0xf6f4f1,
0xf6f4f1,
0xf5f3f0,
0xf5f3f0,
0xf4f2ef,
0xf3f1ee,
0xf3f1ed,
0xf2f0ec,
0xf2efec,
0xf1eeeb,
0xf0edea,
0xb7b5b4,
0xa2a1a1,
0xb9b8b8,
0xc2c0c1,
0xc1c0c0,
0xbbb9ba,
0xcac8c5,
0x999797,
0x747373,
0x737272,
0x7a7979,
0x848382,
0x8f8e8e,
0x9a9999,
0xa6a5a5,
0xb1b0b1,
0xbbb9ba,
0xc1bfc0,
0xc4c2c3,
0xc4c2c3,
0xc1bfc0,
0xbbb9b9,
0xdad6d2,
0xe0dbd6,
0xdfdbd6,
0xdedad5,
0xddd9d4,
0xdcd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd9d6d0,
0xccc9c3,
0xc6c4be,
0xdbd8d3,
0xd4d0ca,
0xcac8c5,
0xe6e6e6,
0xfdfdfc,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xffffff,
0xfafafa,
0xb1b0b0,
0x505050,
0x323232,
0x323232,
0x323232,
0x323232,
0x333333,
0x5c5c5c,
0xd1d1d1,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xffffff,
0xcfcfcf,
0x676767,
0x363636,
0x323232,
0x323232,
0x323232,
0x323232,
0x484847,
0xacacac,
0xfbfbfb,
0xffffff,
0xffffff,
0xe2e2e2,
0x4d4d4d,
0x4e4e4e,
0xa4a4a4,
0xfaf9f9,
0x979797,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x323232,
0x585857,
0xcbcbcb,
0xffffff,
0xffffff,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x757575,
0xf4f4f4,
0xffffff,
0xf2f2f2,
0xe3e3e3,
0xe3e3e3,
0xe3e3e3,
0xe4e4e4,
0xebebeb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 30 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe9e9e9,
0x9f9d9a,
0x787672,
0x393939,
0x323232,
0xa2a1a0,
0xf6f4f1,
0xf5f3f0,
0xf4f2ef,
0xf3f1ee,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xf1efec,
0xf1eeeb,
0xf0edea,
0xf0ede9,
0xd8d6d3,
0x999898,
0xb1b0b0,
0xbfbebe,
0xc2c0c1,
0xbbbabb,
0xa9a8a8,
0x929191,
0x868585,
0x8a8888,
0x939292,
0xa09f9f,
0xabaaaa,
0xb4b2b3,
0xbbb9ba,
0xc3c1c2,
0xceccca,
0xc3c1c2,
0xc3c1c2,
0xc3c1c2,
0xc3c1c2,
0xbcbbbb,
0xcbc8c6,
0xdfdad5,
0xddd9d4,
0xddd9d4,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd5d1cb,
0xbdbbb3,
0xdcd9d6,
0xd4d0ca,
0xd0cdc7,
0xd3d3d3,
0xf7f7f7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xf4f4f4,
0x7b7a7a,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x373737,
0xbcbcbc,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xa7a7a7,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x343434,
0x888888,
0xf9f9f9,
0xffffff,
0xdedede,
0x323232,
0x323232,
0x8f8f8f,
0x7f7f7f,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x353535,
0xc4c4c4,
0xffffff,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x424242,
0x484848,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x595959,
0xc7c7c7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 31 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f4f4,
0xbdbcbb,
0x898782,
0x4b4a4a,
0x323232,
0x5d5d5d,
0xebe9e7,
0xf4f2ef,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xf1efec,
0xf1eeeb,
0xf0eeea,
0xf0edea,
0xf0ede9,
0xefece8,
0xe9e6e3,
0xa7a6a5,
0xa7a6a6,
0xbcbabb,
0xc3c1c2,
0xc0bebf,
0xb6b4b5,
0xa8a7a7,
0xa2a0a0,
0xa5a5a5,
0xafaeae,
0xb8b6b6,
0xbdbcbc,
0xc9c7c6,
0xd7d5d2,
0xe2deda,
0xe3dfda,
0xc6c4c3,
0xbdbbbc,
0xc1bfc0,
0xc3c1c2,
0xc0bebf,
0xbebcbc,
0xdad7d2,
0xdcd9d4,
0xdbd8d3,
0xdad7d2,
0xdad7d1,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xc4c2ba,
0xd0cec8,
0xd7d3cd,
0xd3cfc9,
0xc9c8c6,
0xececec,
0xfefefd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xfafafa,
0x838383,
0x323232,
0x323232,
0x424242,
0x9f9f9f,
0xdbdbdb,
0xe3e3e3,
0xcfcfcf,
0x858585,
0x353535,
0x323232,
0x3a3a39,
0xe3e3e3,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xb6b6b6,
0x383838,
0x323232,
0x363636,
0x818181,
0xcfcfcf,
0xe4e4e4,
0xd9d9d9,
0xa1a0a0,
0x454545,
0x323232,
0x353535,
0xaaaaaa,
0xffffff,
0xdedede,
0x323232,
0x323232,
0x444343,
0x323232,
0x4b4b4b,
0xa9a8a8,
0xdedede,
0xe3e3e3,
0xc3c3c2,
0x5d5d5d,
0x323232,
0x323232,
0x525252,
0xfafafa,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x4f4f4f,
0x6f6f6f,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x353535,
0x777777,
0xe7e7e7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 32 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfb,
0xe0e0e0,
0x92908b,
0x6a6966,
0x353535,
0x343434,
0xc7c6c6,
0xf3f1ee,
0xf2f0ed,
0xf2f0ec,
0xf1efec,
0xf1eeeb,
0xf0edea,
0xf0edea,
0xefece9,
0xefece8,
0xeeebe7,
0xeeebe7,
0xc8c7c4,
0x9c9b9b,
0xb5b4b4,
0xc1bfc0,
0xc3c1c2,
0xbfbdbe,
0xbab8b9,
0xb8b6b7,
0xbab9ba,
0xc1c0c0,
0xd0cecc,
0xdfdcd8,
0xe4e0db,
0xe3dfda,
0xe3dfda,
0xe2deda,
0xcfccc9,
0xafaeae,
0xbab8b9,
0xc1c0c0,
0xc2c0c1,
0xbab9b9,
0xcfcdc9,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd2cec8,
0xbdbbb3,
0xdedbd7,
0xd4d0ca,
0xcbc9c5,
0xdbdbda,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0x515151,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x686868,
0x454545,
0x323232,
0x323232,
0xababab,
0xffffff,
0xc6c6c6,
0x363636,
0x323232,
0x4e4e4e,
0xdddddd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xadacad,
0x323232,
0x323232,
0x808080,
0xfefefe,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xefefef,
0x4c4c4c,
0x323232,
0x393939,
0xb5b5b5,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xd6d6d6,
0x464646,
0x323232,
0x525252,
0xeeeeee,
0xdedede,
0x323232,
0x323232,
0x323232,
0x575757,
0xececec,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf3f3f3,
0x464646,
0x323232,
0x323232,
0xd5d5d5,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x525252,
0xd3d3d3,
0x4b4b4b,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x3d3d3d,
0x9f9f9f,
0xfcfcfc,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 33 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xefefef,
0xacaba9,
0x83807c,
0x424141,
0x323232,
0x7c7c7b,
0xf0efec,
0xf2f0ec,
0xf1eeec,
0xf1eeeb,
0xf0edea,
0xf0edea,
0xefece8,
0xefece8,
0xeeebe7,
0xedeae6,
0xedeae6,
0xe2e0dc,
0x9f9d9d,
0xacabab,
0xbebcbd,
0xc3c1c2,
0xc3c1c2,
0xc3c1c2,
0xc9c7c6,
0xd8d6d3,
0xe3e0dc,
0xe5e2dd,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xe2deda,
0xe1ddd8,
0xdcd8d4,
0xa3a1a1,
0xadacac,
0xbdbcbc,
0xc2c0c1,
0xbebcbd,
0xc1bfbe,
0xd9d6d1,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd8d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xc0bdb5,
0xd6d4d0,
0xd4d0cb,
0xd2cfc9,
0xcbcac9,
0xf1f1f0,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0xababab,
0xfbfbfb,
0x757575,
0x323232,
0x3c3c3c,
0xc6c6c6,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfbfbfb,
0x605f5f,
0x323232,
0x393938,
0xf3f3f3,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xacacac,
0x343434,
0x323232,
0x939393,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x9a9a9a,
0x323232,
0x353535,
0xb8b8b8,
0xdedede,
0x323232,
0x323232,
0x3a3a3a,
0xc6c6c6,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x8a8a8a,
0x323232,
0x323232,
0xb2b2b2,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x525252,
0xefefef,
0xd4d4d4,
0x505050,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x333333,
0x6e6e6e,
0xf9f9f9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 34 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf8f8f7,
0xcecdcd,
0x8d8b86,
0x5c5b59,
0x333333,
0x434343,
0xdcdbd9,
0xf1eeeb,
0xf0eeea,
0xf0edea,
0xefece9,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xece9e5,
0xece9e5,
0xeae8e3,
0xb5b4b2,
0xa1a0a0,
0xb7b6b7,
0xc2c1c1,
0xc4c2c3,
0xc6c4c5,
0xe2dfdb,
0xe5e2dd,
0xe4e1dc,
0xe3dfda,
0xe3dfda,
0xe2deda,
0xe1ddd9,
0xe0dcd7,
0xe0dbd6,
0xe0dbd6,
0xb4b2b0,
0xa09f9f,
0xb7b6b7,
0xc2c0c1,
0xc1c0c0,
0xbbb9b9,
0xd3d1cc,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d3ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xcdcac3,
0xc0beb7,
0xdddad5,
0xd4d0ca,
0xc9c7c4,
0xe1e1e1,
0xfcfcfc,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0xababab,
0xe6e6e6,
0x4b4b4b,
0x323232,
0x5b5b5b,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xa8a8a7,
0x323232,
0x323232,
0xbebebe,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0x707070,
0x323232,
0x393939,
0xdddddd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xdadada,
0x3e3e3e,
0x323232,
0x808080,
0xdedede,
0x323232,
0x323232,
0x535353,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb0b0b0,
0x323232,
0x323232,
0xacacac,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x525252,
0xefefef,
0xffffff,
0xececec,
0x7a7a7a,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x333333,
0x8b8b8b,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 35 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe8e7e7,
0x9c9a96,
0x797873,
0x3a3a3a,
0x323232,
0xa2a1a0,
0xf2efec,
0xf0edea,
0xefece9,
0xefece8,
0xeeebe7,
0xeeebe7,
0xedeae6,
0xece9e5,
0xece9e5,
0xebe8e4,
0xe9e7e2,
0xd6d5d1,
0x999898,
0xb0afaf,
0xbfbebe,
0xc4c2c3,
0xc3c1c2,
0xd6d3d0,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xe2deda,
0xe1ddd8,
0xe0dcd7,
0xe0dbd6,
0xdfdbd6,
0xddd9d4,
0xcecbc7,
0x999999,
0xaeadae,
0xbebdbe,
0xc3c1c2,
0xbcbbbb,
0xc9c7c3,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd3cfc9,
0xbdbab3,
0xdbd8d4,
0xd4d0ca,
0xd1cec8,
0xcececd,
0xf5f4f4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xcbcbcb,
0x323232,
0x323232,
0x878686,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xcacaca,
0x323232,
0x323232,
0x9c9c9b,
0xffffff,
0x565656,
0x323232,
0x494949,
0xeaeaea,
0x454545,
0x323232,
0x575757,
0xf0f0f0,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xeaeaea,
0x515151,
0x323232,
0x5d5d5d,
0xdedede,
0x323232,
0x323232,
0x777777,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x525252,
0xefefef,
0xffffff,
0xffffff,
0xfdfdfd,
0xc1c1c1,
0x525252,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x343434,
0xe1e1e1,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 36 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f4f3,
0xbabab9,
0x898782,
0x4e4d4c,
0x323232,
0x5e5e5e,
0xe7e5e3,
0xefece8,
0xefece8,
0xeeebe7,
0xedeae6,
0xedeae6,
0xece9e5,
0xebe8e4,
0xeae8e3,
0xe9e7e2,
0xe9e7e2,
0xe4e3de,
0xa8a7a5,
0xa6a5a5,
0xbbb9ba,
0xc3c1c2,
0xc3c1c2,
0xc4c1c1,
0xe1ded9,
0xe2deda,
0xe1ddd9,
0xe1ddd8,
0xe0dbd6,
0xe0dbd6,
0xdedad5,
0xddd9d4,
0xdbd8d3,
0xdad7d2,
0xa4a3a2,
0xa5a4a4,
0xbab9b9,
0xc2c0c1,
0xc0bebf,
0xcbc8c6,
0xd8d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xc7c5be,
0xc9c6c0,
0xd9d5d0,
0xd4d0ca,
0xc9c8c5,
0xe8e8e7,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xb3b3b3,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x7e7e7e,
0xfefefe,
0x565656,
0x323232,
0x494949,
0xd6d6d6,
0x404040,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x4e4e4e,
0xcecece,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x525252,
0xefefef,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf5f5f5,
0x949494,
0x373737,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x9d9d9d,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 37 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfbfbfb,
0xdddddd,
0x8f8d8a,
0x6c6a68,
0x363636,
0x363636,
0xc5c4c3,
0xefece8,
0xeeebe7,
0xedeae6,
0xece9e5,
0xece9e5,
0xebe8e4,
0xeae7e3,
0xe9e7e2,
0xe8e6e1,
0xe8e6e1,
0xe7e5e0,
0xc7c5c2,
0x9a9a9a,
0xb4b3b3,
0xc1bfc0,
0xc3c1c2,
0xbdbbbc,
0xd5d2ce,
0xe1ddd9,
0xe0dcd7,
0xe0dbd6,
0xdfdad5,
0xdedad5,
0xdcd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xc6c3c0,
0x9f9d9d,
0xb2b1b2,
0xc1bfc0,
0xc5c3c3,
0xd4d0cc,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd1cec7,
0xbbb8b1,
0xdddad6,
0xd4d0ca,
0xcfcbc6,
0xd4d4d4,
0xf8f8f8,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xa5a5a5,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x7a7a7a,
0xfefefe,
0x565656,
0x323232,
0x494949,
0xcbcbcb,
0x3d3d3d,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x4d4d4d,
0xcccccc,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x424242,
0xa4a4a4,
0xb4b4b4,
0xb4b4b4,
0xb4b4b4,
0xdadada,
0xffffff,
0xfefefe,
0xc6c6c6,
0x3d3d3d,
0x323232,
0x323232,
0x323232,
0x323232,
0x7b7b7b,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 38 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xefeeee,
0xaaa8a7,
0x827f7b,
0x434242,
0x323232,
0x7d7d7c,
0xeeece9,
0xedeae6,
0xece9e5,
0xebe8e4,
0xeae8e3,
0xe9e7e2,
0xe9e7e2,
0xe8e6e1,
0xe8e5e0,
0xe7e4df,
0xe6e3de,
0xdddad6,
0x9d9c9b,
0xabaaaa,
0xbdbcbc,
0xc3c1c2,
0xbfbdbe,
0xc3c1c0,
0xe0dcd7,
0xe0dbd6,
0xdedad5,
0xddd9d4,
0xdbd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd8d5d0,
0xcac8c3,
0xc0bebc,
0xc9c7c5,
0xd4d0cc,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd2cfc8,
0xc1beb8,
0xc7c4be,
0xd5d1cb,
0xd4d0ca,
0xc3c0b9,
0xd3d1cc,
0xd6d2cc,
0xd3cfca,
0xc8c7c6,
0xeeeeed,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xa8a8a8,
0x323232,
0x323232,
0x747474,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xe0e0e0,
0xffffff,
0x565656,
0x323232,
0x494949,
0xcecece,
0x3e3e3e,
0x323232,
0x505050,
0xc4c4c4,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xcfcfcf,
0xd5d5d5,
0xd9d9d9,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xd5d5d5,
0x393939,
0x323232,
0x323232,
0x323232,
0x323232,
0xb1b1b1,
0xffffff,
0xffffff,
0xffffff,
0x787878,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x9a9a9a,
0xffffff,
0xffffff,
0xfefefe,
0x898988,
0x323232,
0x323232,
0x323232,
0x323232,
0x696969,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 39 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf8f8f7,
0xcbcbcb,
0x8d8a86,
0x5e5d5b,
0x343433,
0x454545,
0xd9d8d6,
0xece9e5,
0xebe8e4,
0xe9e7e2,
0xe9e7e2,
0xe8e6e1,
0xe8e6e1,
0xe7e5e0,
0xe6e4df,
0xe5e2dd,
0xe5e2dd,
0xe4e0db,
0xb7b5b3,
0xa09fa0,
0xb7b6b6,
0xc2c0c1,
0xc1c0c0,
0xbab8b8,
0xd9d5d1,
0xdedad5,
0xdcd9d4,
0xdbd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xacaaa3,
0x817f7b,
0x93918e,
0xd7d4d0,
0xd4d0ca,
0xcecac4,
0xc3c1ba,
0xe1deda,
0xd4d0ca,
0xcac8c4,
0xdcdcdc,
0xfafafa,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xc1c1c1,
0x323232,
0x323232,
0x7c7c7c,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xe1e1e1,
0x434343,
0x323232,
0x505050,
0xededed,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xdedede,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x323232,
0xa3a3a3,
0xffffff,
0xffffff,
0xffffff,
0x6d6d6d,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x9a9a9a,
0xffffff,
0xffffff,
0xffffff,
0xa3a3a3,
0x323232,
0x323232,
0x323232,
0x323232,
0x696969,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 40 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe7e7e7,
0x9a9896,
0x797773,
0x3b3b3b,
0x323232,
0xa2a1a0,
0xedeae6,
0xe9e7e2,
0xe8e6e1,
0xe8e6e1,
0xe8e5e0,
0xe7e4df,
0xe6e3de,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe3dfda,
0xd3d0cd,
0x999898,
0xafaeae,
0xbfbebe,
0xc3c1c2,
0xbcbbbb,
0xc9c6c4,
0xdcd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xdad7d1,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d3ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xb5b3ae,
0xadaba4,
0xd2d0ca,
0xe6e4e2,
0xd4d0ca,
0xd1cdc7,
0xc2c0b9,
0xe9e6e4,
0xd4d0ca,
0xd2cfc9,
0xcac9c9,
0xf3f3f3,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xdfdfdf,
0x414141,
0x323232,
0x535353,
0xf8f8f8,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xcfcfcf,
0x7d7d7d,
0x7d7d7d,
0xcacaca,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0x5f5f5f,
0x323232,
0x353535,
0xd7d7d7,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xebebeb,
0x898989,
0x7d7d7d,
0xa2a2a2,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xf6f6f6,
0x3e3e3e,
0x323232,
0x323232,
0x323232,
0x323232,
0x747474,
0xfbfbfb,
0xffffff,
0xefeeee,
0x515151,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x717170,
0xffffff,
0xffffff,
0xfcfcfc,
0x7f7f7f,
0x323232,
0x323232,
0x323232,
0x323232,
0x828282,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 41 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f4f3,
0xb9b9b8,
0x898781,
0x4f4e4d,
0x323232,
0x5f5f5f,
0xe5e3e1,
0xe8e6e1,
0xe8e6e1,
0xe7e5e0,
0xe7e4df,
0xe6e3de,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xdedad7,
0xa8a6a5,
0xa5a4a4,
0xbbb9ba,
0xc2c0c1,
0xc0bebf,
0xc1bfbe,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd6d2cc,
0xe5e3e0,
0xecebe8,
0xdad6d1,
0xd4d0ca,
0xcbc8c2,
0xc7c5bf,
0xeae8e6,
0xd4d0ca,
0xd3cfc9,
0xbfbebc,
0xeaeaea,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xf8f8f8,
0x6a696a,
0x323232,
0x383838,
0xb8b8b8,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfc,
0x6c6c6c,
0x323232,
0x323232,
0xe1e1e1,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xa1a0a0,
0x333333,
0x323232,
0x848484,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xa8a8a7,
0x323232,
0x323232,
0xa3a3a3,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xffffff,
0x696969,
0x323232,
0x323232,
0x323232,
0x323232,
0x373737,
0x9b9b9a,
0xcccccc,
0x878686,
0x353535,
0x323232,
0x323232,
0x323232,
0x323232,
0x5c5c5c,
0x323232,
0x323232,
0x323232,
0x323232,
0x393939,
0x969595,
0xcecece,
0xa4a4a4,
0x3b3b3b,
0x323232,
0x323232,
0x323232,
0x333333,
0xaeaeae,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 42 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfbfbfa,
0xdbdbdb,
0x918e8b,
0x6d6c68,
0x363636,
0x363636,
0xbfbebd,
0xe9e7e2,
0xe7e5e0,
0xe6e4df,
0xe5e2dd,
0xe4e1dc,
0xe4e1dc,
0xe3dfda,
0xe2deda,
0xe1ddd9,
0xe1ddd9,
0xe0dcd7,
0xc5c2bf,
0x9a9999,
0xb3b2b3,
0xc1bfc0,
0xc3c1c2,
0xcac8c6,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0cb,
0xd5d1cb,
0xd4d0ca,
0xd3cfc9,
0xbdbbb3,
0xdeddd9,
0xe3e0dc,
0xd4d0ca,
0xd3cfc9,
0xb5b4b3,
0xe4e4e4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xc3c3c3,
0x363636,
0x323232,
0x494949,
0xd4d4d4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf8f8f8,
0x8f8f8f,
0x323232,
0x323232,
0x767676,
0xfefefe,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xececec,
0x4b4b4b,
0x323232,
0x373736,
0xacacac,
0xfbfbfb,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xbababa,
0x414141,
0x323232,
0x4f4f4f,
0xe7e7e7,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xffffff,
0xacacac,
0x343434,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x3d3d3d,
0xa3a3a3,
0x3a3a3a,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x3b3b3b,
0xefeeee,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 43 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xeeeeee,
0xa9a8a7,
0x82807b,
0x454544,
0x323232,
0x787877,
0xeae8e4,
0xe6e3de,
0xe5e2dd,
0xe4e1dc,
0xe4e0db,
0xe3dfda,
0xe2deda,
0xe1ddd9,
0xe1dcd8,
0xe0dbd6,
0xdfdad5,
0xdbd7d2,
0xb5b3b1,
0xadabac,
0xbdbcbc,
0xc8c6c6,
0xd7d4d0,
0xdad7d2,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd2cec8,
0xc1beb6,
0xc5c4bd,
0xf4f3f1,
0xd7d3cd,
0xd4d0ca,
0xccc9c3,
0xadacac,
0xe4e4e4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xfbfbfb,
0x8c8c8c,
0x323232,
0x323232,
0x373737,
0x777777,
0xa9a9a9,
0xb3b3b3,
0x9b9b9b,
0x545454,
0x323232,
0x323232,
0x484848,
0xe7e7e7,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xbfbfbf,
0x3a3a3a,
0x323232,
0x323232,
0x616161,
0x9d9d9d,
0xb4b4b4,
0xa7a7a7,
0x6c6b6b,
0x353535,
0x323232,
0x3b3b3b,
0xb6b6b6,
0xffffff,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xffffff,
0xf3f3f3,
0x5c5c5c,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x868586,
0xfafafa,
0x8a8a8a,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x333333,
0xa09f9f,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 44 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf7f7f7,
0xcacaca,
0x8b8984,
0x5f5e5c,
0x343434,
0x454545,
0xd5d4d2,
0xe5e2dd,
0xe4e1dc,
0xe3e0db,
0xe3dfda,
0xe1ddd9,
0xe1ddd9,
0xe0dcd7,
0xe0dbd6,
0xdfdad5,
0xddd9d4,
0xddd9d4,
0xdad7d2,
0xd2d0cc,
0xd4d2ce,
0xd8d6d1,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd3cfc9,
0xcecac3,
0xc3c0b8,
0xbbb9b1,
0xcfcdc7,
0xf2f1ef,
0xdfdcd8,
0xd4d0ca,
0xd3cfc9,
0x9c9a96,
0xb4b3b3,
0xeaeae9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7e7e7e,
0x323232,
0x323232,
0xa9a9a9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0x7d7d7d,
0x323232,
0x323232,
0xababab,
0xffffff,
0xffffff,
0xf8f8f8,
0x919191,
0x373737,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x545454,
0xe1e1e1,
0xffffff,
0xffffff,
0xffffff,
0x565656,
0x323232,
0x494949,
0xf2f2f2,
0xffffff,
0xffffff,
0xbcbbbb,
0x444444,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x424242,
0xb5b5b5,
0xffffff,
0xffffff,
0xdedede,
0x323232,
0x323232,
0x818181,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xb4b4b4,
0x323232,
0x323232,
0xacacac,
0xffffff,
0xffffff,
0xe6e6e6,
0x626262,
0x333333,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x343434,
0x7f7e7e,
0xf4f4f4,
0xffffff,
0xf7f7f7,
0x898989,
0x343434,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x323232,
0x343434,
0x9a9a9a,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 45 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe7e6e6,
0x989795,
0x797873,
0x3c3c3c,
0x323232,
0x9c9c9b,
0xe8e5e1,
0xe3dfda,
0xe2deda,
0xe1ddd9,
0xe1ddd8,
0xe0dcd7,
0xdfdbd6,
0xdedad5,
0xddd9d4,
0xdcd8d3,
0xdbd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xcecbc5,
0xc5c3bb,
0xbdbab2,
0xc2c0ba,
0xd7d6d1,
0xecebe9,
0xeeedea,
0xdcd9d4,
0xd4d0ca,
0xd3cfc9,
0x9d9b97,
0x6f6f6e,
0xc3c2c2,
0xf2f2f1,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xbfbfbf,
0x989898,
0x989898,
0xd4d4d4,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xbebebe,
0x989898,
0x989898,
0xd5d5d5,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xd8d8d7,
0x868585,
0x535353,
0x353535,
0x333333,
0x454545,
0x666565,
0xadadad,
0xf9f9f9,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xababab,
0x989898,
0xa4a4a4,
0xf9f9f9,
0xffffff,
0xffffff,
0xffffff,
0xebebeb,
0x9d9d9d,
0x605f5f,
0x3b3b3b,
0x323232,
0x3d3d3d,
0x5a5959,
0x949494,
0xe8e8e8,
0xffffff,
0xffffff,
0xffffff,
0xeeeeee,
0x989898,
0x989898,
0xc0c0c0,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xd9d9d9,
0x999999,
0x989898,
0xd5d5d5,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfc,
0xc1c1c1,
0x7a7a7a,
0x555554,
0x363636,
0x323232,
0x3a3a3a,
0x595958,
0x878787,
0xd0d0d0,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xd5d5d5,
0x8b8b8b,
0x5b5a5a,
0x3c3c3c,
0x323232,
0x383838,
0x5b5b5b,
0x898989,
0xdddddd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 46 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f3f3,
0xb9b8b8,
0x878580,
0x51514f,
0x323232,
0x5c5c5c,
0xe2e0dd,
0xe2deda,
0xe1ddd9,
0xe1dcd7,
0xe0dbd6,
0xdfdad5,
0xded9d4,
0xddd9d4,
0xdcd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xdad7d2,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd0ccc6,
0xc7c4be,
0xbcbab2,
0xc0bfb8,
0xd1d0cb,
0xe9e8e6,
0xeeedeb,
0xe7e5e1,
0xdbd8d3,
0xd5d1cb,
0xd1cdc7,
0xb5b2ae,
0x7a7978,
0x4b4b4b,
0x969595,
0xd6d6d6,
0xf8f8f8,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 47 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfafafa,
0xdadada,
0x8f8d8a,
0x6e6c69,
0x373636,
0x373737,
0xbebdbc,
0xe4e0db,
0xe0dcd7,
0xdfdbd6,
0xdedad5,
0xddd9d4,
0xdcd9d4,
0xdbd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd1cdc7,
0xcac6c0,
0xbfbcb5,
0xbebcb5,
0xceccc7,
0xe5e4e1,
0xefeeec,
0xeae8e4,
0xdddad5,
0xd6d2cc,
0xd2cec8,
0xbdbab4,
0x94928f,
0x626160,
0x424141,
0x444343,
0x807f7f,
0xbcbbbc,
0xeaeaea,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 48 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xeeeeee,
0xa8a7a5,
0x817f7a,
0x464544,
0x333333,
0xa6a5a5,
0xe6e3e0,
0xdfdbd6,
0xded9d4,
0xddd9d4,
0xdcd8d3,
0xdbd8d3,
0xdbd8d3,
0xdad7d2,
0xdad7d2,
0xd9d6d1,
0xd9d6d0,
0xd8d5cf,
0xd8d5cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd2cec8,
0xcbc8c1,
0xc0bdb5,
0xbebcb5,
0xc9c7c1,
0xe2e1de,
0xeeedeb,
0xeceae8,
0xdfdcd8,
0xd7d3cd,
0xd3cfc9,
0xc2beb9,
0x9f9d98,
0x6b6a67,
0x4a4948,
0x3b3b3b,
0x474746,
0x626161,
0x8b8a8a,
0xb7b6b6,
0xe0e0df,
0xf8f8f8,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 49 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf7f7f7,
0xc9c8c8,
0x8b8884,
0x5f5f5d,
0x5d5c5c,
0xd3d2d0,
0xe2dfdb,
0xddd9d4,
0xddd9d4,
0xdcd8d3,
0xdbd8d3,
0xd0cdc8,
0xc7c4c0,
0xd4d2cd,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d4ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd4d0ca,
0xd4d0ca,
0xd3cfc9,
0xcdc9c3,
0xc2bfb8,
0xbdbbb3,
0xc5c3bd,
0xdddcd8,
0xedecea,
0xeeedeb,
0xe1deda,
0xd8d4cf,
0xd3d0ca,
0xc6c2bd,
0xa8a5a1,
0x747371,
0x4f4f4f,
0x3d3d3d,
0x444444,
0x5b5b5a,
0x777777,
0x939392,
0xababab,
0xc8c7c7,
0xe4e4e4,
0xf7f7f7,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 50 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xe6e6e6,
0x989794,
0x83817d,
0xc4c3c2,
0xcbc9c2,
0xd5d3ce,
0xdfdbd6,
0xdbd8d3,
0xdbd8d3,
0xd5d2cd,
0x94928d,
0x85837e,
0xaaa8a4,
0xe1deda,
0xd8d5cf,
0xd8d4cf,
0xd7d3ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd3cfc9,
0xcfcbc5,
0xc5c2ba,
0xbebbb3,
0xc2c0b9,
0xd8d7d3,
0xebeae8,
0xefeeec,
0xe4e1dd,
0xd9d6d0,
0xd4d0ca,
0xcac6c0,
0xafaca8,
0x807f7c,
0x565655,
0x3e3e3e,
0x444343,
0x555454,
0x717070,
0x8d8b8c,
0xa6a5a5,
0xbcbbbb,
0xd0d0d0,
0xe2e2e2,
0xf1f1f1,
0xfafafa,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 51 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f3f3,
0xb8b8b7,
0x9d9b96,
0xd8d5d1,
0xd3d0ca,
0xc2c0ba,
0xe1deda,
0xdbd8d3,
0xdad7d2,
0xd5d3ce,
0xa7a5a2,
0xc2c0b9,
0xd8d7d5,
0xe3e1dd,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xcfccc5,
0xc7c4be,
0xbdbbb3,
0xc0beb7,
0xd3d2cd,
0xe8e8e5,
0xf1f0ef,
0xe6e4e0,
0xdbd8d3,
0xd4d1cb,
0xccc8c3,
0xb8b5b0,
0x898785,
0x5f5e5c,
0x444343,
0x444443,
0x515151,
0x6b6b6a,
0x868685,
0xa09f9f,
0xb6b5b5,
0xcccbcb,
0xdedede,
0xececec,
0xf6f6f6,
0xfcfcfc,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 52 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfafafa,
0xd9d9d9,
0x8c8a87,
0xbfbcb7,
0xd8d4ce,
0xc0beb7,
0xdcd9d4,
0xdbd8d3,
0xdad7d2,
0xd9d6d0,
0xe0ddd9,
0xebeae7,
0xeae9e6,
0xd9d5d0,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd6d2cc,
0xd5d1cb,
0xd2cec8,
0xc9c7c0,
0xbebbb4,
0xbdbbb4,
0xceccc7,
0xe6e5e2,
0xf1f0ee,
0xe9e7e4,
0xdcd9d4,
0xd5d1cb,
0xd0ccc6,
0xbdbab4,
0x95938f,
0x656463,
0x474747,
0x444443,
0x4f4f4e,
0x646464,
0x807f7e,
0x9b9a9a,
0xb1b0b0,
0xc7c6c6,
0xdadada,
0xe9e9e9,
0xf4f4f4,
0xfbfbfb,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 53 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xeeeeed,
0x9c9b9a,
0x92908d,
0xd5d2cc,
0xceccc6,
0xc4c2bb,
0xdcd9d4,
0xd9d6d0,
0xd9d6d0,
0xd8d5cf,
0xd8d4cf,
0xd7d3ce,
0xd7d3cd,
0xd7d3cd,
0xd6d2cc,
0xd3cfc9,
0xcdc9c3,
0xc0beb6,
0xbdbbb3,
0xc9c8c1,
0xe2e1de,
0xf1f1ef,
0xebe9e6,
0xdfdcd7,
0xd5d1cb,
0xd1cdc7,
0xc2bfba,
0x9d9a96,
0x6f6e6b,
0x4d4c4b,
0x464544,
0x4c4c4b,
0x60605f,
0x7a7a79,
0x959595,
0xababab,
0xc1c1c1,
0xd6d5d5,
0xe7e7e6,
0xf3f2f2,
0xfafaf9,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 54 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf7f7f7,
0xc7c7c6,
0x787775,
0xc8c4be,
0xd7d4cf,
0xc3c1b9,
0xc4c2ba,
0xd4d1cb,
0xd8d5cf,
0xd8d4cf,
0xd7d3cd,
0xd7d3cd,
0xd5d1cb,
0xcfcbc5,
0xc3c0b8,
0xbdbbb4,
0xc3c1bb,
0xdfdedb,
0xefeeed,
0xefedeb,
0xe0deda,
0xd7d3cd,
0xd2cec8,
0xc7c3bd,
0xa6a39e,
0x757371,
0x525150,
0x454544,
0x4b4a49,
0x5c5b5a,
0x767575,
0x909090,
0xa7a6a6,
0xbdbdbd,
0xd1d1d1,
0xe2e2e1,
0xf0efef,
0xf8f8f8,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 55 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfc,
0xe6e6e5,
0x848382,
0xa5a39e,
0xd6d2cc,
0xd7d4ce,
0xc8c5be,
0xbcbab2,
0xc4c1ba,
0xcbc8c1,
0xccc9c2,
0xc4c1ba,
0xbdbbb3,
0xc1bfb8,
0xd8d7d3,
0xededeb,
0xf1f0ee,
0xe3e1dd,
0xd8d4cf,
0xd3cfca,
0xcac6c1,
0xafaca7,
0x7d7b78,
0x555452,
0x454443,
0x494847,
0x575555,
0x706f6f,
0x8a8989,
0xa2a1a1,
0xb8b7b8,
0xcecdcd,
0xe0e0df,
0xeeeeed,
0xf7f7f7,
0xfcfcfc,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 56 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf4f3f3,
0xb2b2b2,
0x797875,
0xcdc9c3,
0xd6d3cd,
0xd9d6d0,
0xdcd9d5,
0xd8d7d2,
0xcfcdc7,
0xd0cec9,
0xdcdad7,
0xeae9e6,
0xf3f2f1,
0xe6e3e0,
0xdad6d0,
0xd4d0ca,
0xcdc9c3,
0xb5b2ad,
0x878581,
0x5d5c5a,
0x464544,
0x474645,
0x515050,
0x696968,
0x848483,
0x9d9c9c,
0xb3b2b2,
0xc8c8c8,
0xdcdcdc,
0xebebeb,
0xf6f6f5,
0xfbfbfb,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 57 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfafafa,
0xd8d8d8,
0x71706f,
0x92908c,
0xd1cec8,
0xd6d2cc,
0xd7d3cd,
0xd8d4ce,
0xdfdbd6,
0xe2dfdb,
0xe1deda,
0xdbd7d2,
0xd4d0ca,
0xcfcbc5,
0xbfbcb6,
0x8e8c89,
0x646260,
0x494847,
0x494847,
0x504f4e,
0x646362,
0x7e7d7d,
0x979696,
0xadacac,
0xc4c3c3,
0xd8d7d7,
0xe8e8e8,
0xf3f3f3,
0xfafafa,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 58 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfefefe,
0xeeeeed,
0x9f9e9e,
0x5a5958,
0x878683,
0xc6c2bd,
0xd3cfc9,
0xd5d1cb,
0xd5d1cb,
0xd4d0ca,
0xd1cdc7,
0xc4c0bb,
0x9a9894,
0x6c6b68,
0x4d4c4b,
0x494847,
0x4d4c4b,
0x5f5e5d,
0x777776,
0x929292,
0xa8a7a7,
0xbebdbe,
0xd4d3d2,
0xe5e5e5,
0xf1f1f1,
0xf9f9f9,
0xfdfdfd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 59 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xf8f8f7,
0xd5d4d4,
0x7c7c7b,
0x555452,
0x5f5e5c,
0x82807c,
0x989692,
0x9a9894,
0x92908c,
0x747371,
0x525251,
0x4a4948,
0x4e4d4c,
0x5a5a59,
0x717171,
0x8c8b8c,
0xa3a2a2,
0xb9b9b9,
0xd0cfcf,
0xe1e1e1,
0xeeeeee,
0xf7f7f7,
0xfcfcfc,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 60 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfdfdfd,
0xefefef,
0xc5c5c5,
0x807f7e,
0x585755,
0x525150,
0x51504f,
0x4f4f4e,
0x4e4e4d,
0x4f4f4e,
0x595857,
0x6d6c6b,
0x878787,
0x9e9d9d,
0xb4b3b4,
0xcacaca,
0xdddddd,
0xededec,
0xf7f7f6,
0xfcfcfc,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 61 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfb,
0xebebea,
0xcacaca,
0xa09f9f,
0x7b7b7a,
0x6b6b6a,
0x686868,
0x6f6f6e,
0x838281,
0x9a9999,
0xafaeae,
0xc5c5c5,
0xdadad9,
0xe9e9e9,
0xf4f4f3,
0xfbfbfb,
0xfefefe,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 62 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xfcfcfb,
0xf0f0f0,
0xdcdcdb,
0xc7c7c7,
0xb8b7b7,
0xb2b2b2,
0xb6b6b6,
0xc4c3c3,
0xd5d5d5,
0xe6e6e6,
0xf3f3f2,
0xfafafa,
0xfefefd,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 63 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 64 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
/* Scanline 65 */
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
0xffffff,
 
};
 
/** @}
*/
Property changes:
Added: svn:mergeinfo
/branches/arm/kernel/genarch/Makefile.inc
33,75 → 33,96
genarch/src/acpi/acpi.c \
genarch/src/acpi/madt.c
endif
 
ifeq ($(CONFIG_PAGE_PT),y)
GENARCH_SOURCES += \
genarch/src/mm/page_pt.c \
genarch/src/mm/as_pt.c
endif
 
ifeq ($(CONFIG_PAGE_HT),y)
GENARCH_SOURCES += \
genarch/src/mm/page_ht.c \
genarch/src/mm/as_ht.c
endif
 
ifeq ($(CONFIG_ASID),y)
GENARCH_SOURCES += \
genarch/src/mm/asid.c
endif
 
ifeq ($(CONFIG_ASID_FIFO),y)
GENARCH_SOURCES += \
genarch/src/mm/asid_fifo.c
endif
 
ifeq ($(CONFIG_SOFTINT),y)
GENARCH_SOURCES += \
genarch/src/softint/division.c
endif
 
## Framebuffer
ifeq ($(CONFIG_FB),y)
GENARCH_SOURCES += \
genarch/src/fb/font-8x16.c \
genarch/src/fb/logo-196x66.c \
genarch/src/fb/fb.c
DEFS += -DCONFIG_FB
endif
 
## i8042 controller
ifeq ($(CONFIG_I8042),y)
ifeq ($(CONFIG_DSRLNIN),y)
GENARCH_SOURCES += \
genarch/src/kbd/i8042.c \
genarch/src/kbd/key.c \
genarch/src/kbd/scanc_pc.c
genarch/src/drivers/dsrln/dsrlnin.c
endif
 
## pl050 controller
ifeq ($(CONFIG_PL050),y)
ifeq ($(CONFIG_DSRLNOUT),y)
GENARCH_SOURCES += \
genarch/src/kbd/key.c \
genarch/src/kbd/scanc_pl050.c
DEFS += -DCONFIG_PL050
genarch/src/drivers/dsrln/dsrlnout.c
endif
## Sun keyboard
ifeq ($(CONFIG_SUN_KBD),y)
 
ifeq ($(CONFIG_I8042),y)
GENARCH_SOURCES += \
genarch/src/kbd/key.c \
genarch/src/kbd/scanc_sun.c
genarch/src/drivers/i8042/i8042.c
endif
 
## z8530 controller
ifeq ($(CONFIG_NS16550),y)
GENARCH_SOURCES += \
genarch/src/drivers/ns16550/ns16550.c
endif
 
ifeq ($(CONFIG_Z8530),y)
GENARCH_SOURCES += \
genarch/src/kbd/z8530.c
genarch/src/drivers/z8530/z8530.c
endif
 
## ns16550 controller
ifeq ($(CONFIG_NS16550),y)
ifeq ($(CONFIG_VIA_CUDA),y)
GENARCH_SOURCES += \
genarch/src/kbd/ns16550.c
genarch/src/drivers/via-cuda/cuda.c
endif
 
ifeq ($(CONFIG_PC_KBD),y)
GENARCH_SOURCES += \
genarch/src/kbrd/kbrd.c \
genarch/src/kbrd/scanc_pc.c
endif
 
## OpenFirmware Device Tree
ifeq ($(CONFIG_OFW_TREE), y)
ifeq ($(CONFIG_SUN_KBD),y)
GENARCH_SOURCES += \
genarch/src/kbrd/kbrd.c \
genarch/src/kbrd/scanc_sun.c
endif
 
ifeq ($(CONFIG_MAC_KBD),y)
GENARCH_SOURCES += \
genarch/src/kbrd/kbrd.c \
genarch/src/kbrd/scanc_mac.c
endif
 
ifeq ($(CONFIG_SRLN),y)
GENARCH_SOURCES += \
genarch/src/srln/srln.c
endif
 
ifeq ($(CONFIG_OFW_TREE),y)
GENARCH_SOURCES += \
genarch/src/ofw/ofw_tree.c \
genarch/src/ofw/ebus.c \
genarch/src/ofw/fhc.c \
109,3 → 130,13
genarch/src/ofw/sbus.c \
genarch/src/ofw/upa.c
endif
 
ifeq ($(CONFIG_MULTIBOOT), y)
GENARCH_SOURCES += \
genarch/src/multiboot/multiboot.c
endif
 
ifeq ($(CONFIG_EGA), y)
GENARCH_SOURCES += \
genarch/src/drivers/ega/ega.c
endif
/branches/arm/kernel/doc/mm
5,10 → 5,10
 
1.1 Hierarchical 4-level per address space page tables
 
SPARTAN kernel deploys generic interface for 4-level page tables
for these architectures: amd64, ia32, mips32 and ppc32. In this
setting, page tables are hierarchical and are not shared by
address spaces (i.e. one set of page tables per address space).
SPARTAN kernel deploys generic interface for 4-level page tables for these
architectures: amd64, arm32, ia32, mips32 and ppc32. In this setting, page
tables are hierarchical and are not shared by address spaces (i.e. one set of
page tables per address space).
 
 
VADDR
/branches/arm/kernel/Makefile
30,23 → 30,28
## Include configuration
#
 
-include ../version
-include Makefile.config
include ../version
-include ../Makefile.config
-include ../config.defs
 
INCLUDES = generic/include
OPTIMIZATION = 3
 
ifndef CROSS_PREFIX
CROSS_PREFIX = /usr/local
endif
 
## Common compiler flags
#
 
DEFS = -D$(ARCH) -DARCH=\"$(ARCH)\" -DRELEASE=\"$(RELEASE)\" "-DNAME=\"$(NAME)\"" \
-DKERNEL
DEFS = -DKERNEL -DRELEASE=$(RELEASE) "-DNAME=$(NAME)" -D__$(BITS)_BITS__ -D__$(ENDIANESS)__
 
GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) \
-fno-builtin -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Werror \
-nostdlib -nostdinc
GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \
-fexec-charset=UTF-8 -fwide-exec-charset=UTF-32$(ENDIANESS) \
-finput-charset=UTF-8 -fno-builtin -Wall -Wextra -Wno-unused-parameter \
-Wmissing-prototypes -Werror -nostdlib -nostdinc -pipe
 
ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) \
ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \
-fno-builtin -Wall -Wmissing-prototypes -Werror \
-nostdlib -nostdinc \
-wd170
58,15 → 63,7
LFLAGS = -M
AFLAGS =
 
ifdef REVISION
DEFS += "-DREVISION=\"$(REVISION)\""
endif
 
ifdef TIMESTAMP
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\""
endif
 
-include arch/$(ARCH)/Makefile.inc
-include arch/$(KARCH)/Makefile.inc
-include genarch/Makefile.inc
 
## The at-sign
84,76 → 81,6
#
SYMTAB_SECTION=".section symtab.data, \"a\", $(ATSIGN)progbits;"
 
## Setup kernel configuration
#
ifeq ($(CONFIG_DEBUG),y)
DEFS += -DCONFIG_DEBUG
endif
 
ifeq ($(CONFIG_EDEBUG),y)
DEFS += -DCONFIG_EDEBUG
endif
 
ifeq ($(CONFIG_DEBUG_SPINLOCK),y)
DEFS += -DCONFIG_DEBUG_SPINLOCK
endif
 
ifeq ($(CONFIG_DEBUG_AS_WATCHPOINT),y)
DEFS += -DCONFIG_DEBUG_AS_WATCHPOINT
endif
 
ifeq ($(CONFIG_FPU_LAZY),y)
DEFS += -DCONFIG_FPU_LAZY
endif
 
ifeq ($(CONFIG_DEBUG_ALLREGS),y)
DEFS += -DCONFIG_DEBUG_ALLREGS
endif
 
ifeq ($(CONFIG_VHPT),y)
DEFS += -DCONFIG_VHPT
endif
 
ifeq ($(CONFIG_TSB),y)
DEFS += -DCONFIG_TSB
endif
 
ifeq ($(CONFIG_Z8530),y)
DEFS += -DCONFIG_Z8530
endif
 
ifeq ($(CONFIG_NS16550),y)
DEFS += -DCONFIG_NS16550
endif
 
ifeq ($(CONFIG_VIRT_IDX_DCACHE),y)
DEFS += -DCONFIG_VIRT_IDX_DCACHE
endif
 
ifeq ($(CONFIG_FB),y)
ifeq ($(ARCH),ia32)
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH)
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT)
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP)
endif
ifeq ($(ARCH),amd64)
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH)
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT)
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP)
endif
ifeq ($(ARCH),ia32xen)
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH)
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT)
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP)
endif
endif
 
ifeq ($(CONFIG_UDEBUG),y)
DEFS += -DCONFIG_UDEBUG
endif
 
## Simple detection for the type of the host system
#
HOST = $(shell uname)
178,6 → 105,7
OBJDUMP = $(BINUTILS_PREFIX)objdump
LIBDIR = /usr/lib
CFLAGS = $(GCC_CFLAGS)
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
endif
 
ifeq ($(COMPILER),icc_native)
189,6 → 117,7
OBJDUMP = objdump
LIBDIR = /usr/lib
CFLAGS = $(ICC_CFLAGS)
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
endif
 
ifeq ($(COMPILER),suncc_native)
200,6 → 129,8
OBJDUMP = $(BINUTILS_PREFIX)objdump
LIBDIR = /usr/lib
CFLAGS = $(SUNCC_CFLAGS)
DEFS += $(CONFIG_DEFS)
DEPEND_DEFS = $(DEFS)
endif
 
ifeq ($(COMPILER),gcc_cross)
211,6 → 142,7
OBJDUMP = $(TOOLCHAIN_DIR)/bin/$(TARGET)-objdump
LIBDIR = $(TOOLCHAIN_DIR)/lib
CFLAGS = $(GCC_CFLAGS)
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS)
endif
 
## Generic kernel sources
224,12 → 156,11
generic/src/adt/list.c \
generic/src/console/chardev.c \
generic/src/console/console.c \
generic/src/console/kconsole.c \
generic/src/console/cmd.c \
generic/src/cpu/cpu.c \
generic/src/ddi/ddi.c \
generic/src/ddi/irq.c \
generic/src/ddi/device.c \
generic/src/debug/symtab.c \
generic/src/interrupt/interrupt.c \
generic/src/main/main.c \
generic/src/main/kinit.c \
256,16 → 187,14
generic/src/lib/func.c \
generic/src/lib/memstr.c \
generic/src/lib/sort.c \
generic/src/lib/string.c \
generic/src/lib/elf.c \
generic/src/lib/rd.c \
generic/src/printf/printf_core.c \
generic/src/printf/printf.c \
generic/src/printf/sprintf.c \
generic/src/printf/snprintf.c \
generic/src/printf/vprintf.c \
generic/src/printf/vsprintf.c \
generic/src/printf/vsnprintf.c \
generic/src/debug/symtab.c \
generic/src/time/clock.c \
generic/src/time/timeout.c \
generic/src/time/delay.c \
284,9 → 213,19
generic/src/ipc/sysipc.c \
generic/src/ipc/ipcrsc.c \
generic/src/ipc/irq.c \
generic/src/ipc/event.c \
generic/src/security/cap.c \
generic/src/sysinfo/sysinfo.c
 
## Kernel console support
#
 
ifeq ($(CONFIG_KCONSOLE),y)
GENERIC_SOURCES += \
generic/src/console/kconsole.c \
generic/src/console/cmd.c
endif
 
## Udebug interface sources
#
 
302,7 → 241,6
#
 
ifeq ($(CONFIG_TEST),y)
DEFS += -DCONFIG_TEST
CFLAGS += -Itest/
GENERIC_SOURCES += \
test/test.c \
309,17 → 247,12
test/atomic/atomic1.c \
test/btree/btree1.c \
test/avltree/avltree1.c \
test/debug/mips1.c \
test/fault/fault1.c \
test/fpu/fpu1.c \
test/fpu/sse1.c \
test/fpu/mips2.c \
test/mm/falloc1.c \
test/mm/falloc2.c \
test/mm/mapping1.c \
test/mm/slab1.c \
test/mm/slab2.c \
test/mm/purge1.c \
test/synch/rwlock1.c \
test/synch/rwlock2.c \
test/synch/rwlock3.c \
328,8 → 261,63
test/synch/semaphore1.c \
test/synch/semaphore2.c \
test/print/print1.c \
test/print/print2.c \
test/print/print3.c \
test/print/print4.c \
test/thread/thread1.c \
test/sysinfo/sysinfo1.c
ifeq ($(KARCH),mips32)
GENERIC_SOURCES += test/debug/mips1.c
else
GENERIC_SOURCES += test/debug/mips1_skip.c
endif
ifeq ($(KARCH),ia64)
GENERIC_SOURCES += test/mm/purge1.c
else
GENERIC_SOURCES += test/mm/purge1_skip.c
endif
ifeq ($(CONFIG_FPU),y)
ifeq ($(KARCH),ia32)
TEST_FPU1 = y
TEST_SSE1 = y
GENERIC_SOURCES += test/fpu/fpu1_x86.c
endif
ifeq ($(KARCH),amd64)
TEST_FPU1 = y
TEST_SSE1 = y
GENERIC_SOURCES += test/fpu/fpu1_x86.c
endif
ifeq ($(KARCH),ia64)
TEST_FPU1 = y
GENERIC_SOURCES += test/fpu/fpu1_ia64.c
endif
ifeq ($(KARCH),mips32)
TEST_MIPS2 = y
endif
endif
ifneq ($(TEST_FPU1),y)
GENERIC_SOURCES += test/fpu/fpu1_skip.c
endif
ifeq ($(TEST_SSE1),y)
GENERIC_SOURCES += test/fpu/sse1.c
else
GENERIC_SOURCES += test/fpu/sse1_skip.c
endif
ifeq ($(TEST_MIPS2),y)
GENERIC_SOURCES += test/fpu/mips2.c
else
GENERIC_SOURCES += test/fpu/mips2_skip.c
endif
endif
 
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES)))
336,25 → 324,24
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES)))
GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES)))
 
.PHONY: all build config distclean clean archlinks depend disasm
ifeq ($(CONFIG_SYMTAB),y)
SYMTAB_OBJECTS := generic/src/debug/real_map.o
else
SYMTAB_OBJECTS :=
endif
 
all:
../tools/config.py kernel.config default $(ARCH) $(COMPILER) $(CONFIG_DEBUG) $(MACHINE)
.PHONY: all build clean archlinks depend disasm
 
all: ../Makefile.config ../config.h ../config.defs
-rm Makefile.depend
$(MAKE) -C . build
 
build: kernel.bin disasm
 
config:
-rm Makefile.depend
../tools/config.py kernel.config
 
-include Makefile.depend
 
distclean: clean
-rm Makefile.config
 
clean:
-rm -f kernel.bin kernel.raw kernel.map kernel.map.pre kernel.objdump kernel.disasm generic/src/debug/real_map.bin Makefile.depend* generic/include/arch generic/include/genarch arch/$(ARCH)/_link.ld
-rm -f kernel.bin kernel.raw kernel.map kernel.map.pre kernel.objdump kernel.disasm generic/src/debug/real_map.bin Makefile.depend* generic/include/arch generic/include/genarch arch/$(KARCH)/_link.ld
find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o' -follow -exec rm \{\} \;
for arch in arch/* ; do \
[ -e $$arch/_link.ld ] && rm $$arch/_link.ld 2>/dev/null ; \
361,24 → 348,24
done ; exit 0
 
archlinks:
ln -sfn ../../arch/$(ARCH)/include/ generic/include/arch
ln -sfn ../../arch/$(KARCH)/include/ generic/include/arch
ln -sfn ../../genarch/include/ generic/include/genarch
 
depend: archlinks
-makedepend $(DEFS) $(CFLAGS) -f - $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null
 
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in
arch/$(KARCH)/_link.ld: arch/$(KARCH)/_link.ld.in
$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -D__LINKER__ -E -x c $< | grep -v "^\#" > $@
 
generic/src/debug/real_map.bin: depend arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS)
generic/src/debug/real_map.bin: depend arch/$(KARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS)
echo $(SYMTAB_SECTION) | $(AS) $(AFLAGS) -o generic/src/debug/empty_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/empty_map.o -o $@ -Map kernel.map.pre
$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/empty_map.o -o $@ -Map kernel.map.pre
$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > kernel.objdump
tools/genmap.py kernel.map.pre kernel.objdump generic/src/debug/real_map.bin
# Do it once again, this time to get correct even the symbols
# on architectures, that have bss after symtab
echo $(SYMTAB_SECTION)" .incbin \"$@\"" | $(AS) $(AFLAGS) -o generic/src/debug/sizeok_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/sizeok_map.o -o $@ -Map kernel.map.pre
$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/sizeok_map.o -o $@ -Map kernel.map.pre
$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > kernel.objdump
tools/genmap.py kernel.map.pre kernel.objdump generic/src/debug/real_map.bin
 
385,8 → 372,8
generic/src/debug/real_map.o: generic/src/debug/real_map.bin
echo $(SYMTAB_SECTION)" .incbin \"$<\"" | $(AS) $(AFLAGS) -o $@
 
kernel.raw: depend arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) generic/src/debug/real_map.o
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/real_map.o -o $@ -Map kernel.map
kernel.raw: depend arch/$(KARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(SYMTAB_OBJECTS)
$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) $(SYMTAB_OBJECTS) -o $@ -Map kernel.map
 
kernel.bin: kernel.raw
$(OBJCOPY) -O $(BFD) kernel.raw kernel.bin
/branches/arm/kernel/test/avltree/avltree1.c
41,7 → 41,7
*/
static avltree_node_t avltree_nodes[NODE_COUNT];
 
/*
/*
* head of free nodes' list:
*/
static avltree_node_t *first_free_node = NULL;
58,11 → 58,11
if (!node)
return NULL;
 
if (node->lft) {
tmp = test_tree_parents(node->lft);
if (tmp != node) {
printf("Bad parent pointer key: %" PRIu64
TPRINTF("Bad parent pointer key: %" PRIu64
", address: %p\n", tmp->key, node->lft);
}
}
69,7 → 69,7
if (node->rgt) {
tmp = test_tree_parents(node->rgt);
if (tmp != node) {
printf("Bad parent pointer key: %" PRIu64
TPRINTF("Bad parent pointer key: %" PRIu64
", address: %p\n",
tmp->key,node->rgt);
}
80,49 → 80,50
int test_tree_balance(avltree_node_t *node)
{
int h1, h2, diff;
 
if (!node)
return 0;
h1 = test_tree_balance(node->lft);
h2 = test_tree_balance(node->rgt);
diff = h2 - h1;
if (diff != node->balance || (diff != -1 && diff != 0 && diff != 1)) {
printf("Bad balance\n");
}
return h1 > h2 ? h1 + 1 : h2 + 1;
if ((diff != node->balance) || ((diff != -1) && (diff != 0) && (diff != 1)))
TPRINTF("Bad balance\n");
return ((h1 > h2) ? (h1 + 1) : (h2 + 1));
}
 
/**
* Prints the structure of the node, which is level levels from the top of the
* tree.
* tree.
*/
static void
print_tree_structure_flat(avltree_node_t *node, int level)
static void print_tree_structure_flat(avltree_node_t *node, int level)
{
/*
* You can set the maximum level as high as you like.
* Most of the time, you'll want to debug code using small trees,
* so that a large level indicates a loop, which is a bug.
* Most of the time, you'll want to debug code using small trees,
* so that a large level indicates a loop, which is a bug.
*/
if (level > 16) {
printf("[...]");
TPRINTF("[...]");
return;
}
 
if (node == NULL)
return;
 
printf("%" PRIu64 "[%" PRIu8 "]", node->key, node->balance);
TPRINTF("%" PRIu64 "[%" PRIu8 "]", node->key, node->balance);
if (node->lft != NULL || node->rgt != NULL) {
printf("(");
 
TPRINTF("(");
print_tree_structure_flat(node->lft, level + 1);
if (node->rgt != NULL) {
printf(",");
TPRINTF(",");
print_tree_structure_flat(node->rgt, level + 1);
}
 
printf(")");
TPRINTF(")");
}
}
 
129,10 → 130,10
static void alloc_avltree_node_prepare(void)
{
int i;
 
for (i = 0; i < NODE_COUNT - 1; i++) {
for (i = 0; i < NODE_COUNT - 1; i++)
avltree_nodes[i].par = &avltree_nodes[i + 1];
}
avltree_nodes[i].par = NULL;
/*
139,37 → 140,44
* Node keys which will be used for insertion. Up to NODE_COUNT size of
* array.
*/
 
/* First tree node and same key */
avltree_nodes[0].key = 60;
avltree_nodes[1].key = 60;
avltree_nodes[2].key = 60;
/* LL rotation */
avltree_nodes[3].key = 50;
avltree_nodes[4].key = 40;
avltree_nodes[5].key = 30;
/* LR rotation */
avltree_nodes[6].key = 20;
avltree_nodes[7].key = 20;
avltree_nodes[8].key = 25;
avltree_nodes[9].key = 25;
/* LL rotation in lower floor */
avltree_nodes[10].key = 35;
/* RR rotation */
avltree_nodes[11].key = 70;
avltree_nodes[12].key = 80;
/* RL rotation */
avltree_nodes[13].key = 90;
avltree_nodes[14].key = 85;
/* Insert 0 key */
avltree_nodes[15].key = 0;
avltree_nodes[16].key = 0;
/* Insert reverse */
avltree_nodes[17].key = 600;
avltree_nodes[18].key = 500;
avltree_nodes[19].key = 400;
avltree_nodes[20].key = 300;
 
for (i = 21; i < NODE_COUNT; i++)
avltree_nodes[i].key = i * 3;
179,40 → 187,35
static avltree_node_t *alloc_avltree_node(void)
{
avltree_node_t *node;
 
node = first_free_node;
first_free_node = first_free_node->par;
 
return node;
}
 
static void test_tree_insert(avltree_t *tree, count_t node_count, bool quiet)
static void test_tree_insert(avltree_t *tree, size_t node_count)
{
unsigned int i;
avltree_node_t *newnode;
 
avltree_create(tree);
if (!quiet)
printf("Inserting %" PRIc " nodes...", node_count);
 
TPRINTF("Inserting %" PRIs " nodes...", node_count);
for (i = 0; i < node_count; i++) {
newnode = alloc_avltree_node();
avltree_insert(tree, newnode);
if (!quiet) {
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
if (!quiet)
printf("done.\n");
TPRINTF("done.\n");
}
 
 
static void test_tree_delete(avltree_t *tree, count_t node_count,
int node_position, bool quiet)
static void test_tree_delete(avltree_t *tree, size_t node_count,
int node_position)
{
avltree_node_t *delnode;
unsigned int i;
219,71 → 222,61
switch (node_position) {
case 0:
if (!quiet)
printf("Deleting root nodes...");
TPRINTF("Deleting root nodes...");
while (tree->root != NULL) {
delnode = tree->root;
avltree_delete(tree, delnode);
if (!quiet) {
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
}
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
break;
case 1:
if (!quiet)
printf("Deleting nodes according to creation time...");
TPRINTF("Deleting nodes according to creation time...");
for (i = 0; i < node_count; i++) {
avltree_delete(tree, &avltree_nodes[i]);
if (!quiet) {
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
break;
break;
}
if (!quiet)
printf("done.\n");
TPRINTF("done.\n");
}
 
static void test_tree_delmin(avltree_t *tree, count_t node_count, bool quiet)
static void test_tree_delmin(avltree_t *tree, size_t node_count)
{
unsigned int i = 0;
if (!quiet)
printf("Deleting minimum nodes...");
TPRINTF("Deleting minimum nodes...");
while (tree->root != NULL) {
i++;
avltree_delete_min(tree);
if (!quiet) {
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
test_tree_parents(tree->root);
test_tree_balance(tree->root);
}
 
if (!quiet && (i != node_count))
printf("Bad node count. Some nodes have been lost!\n");
 
if (!quiet)
printf("done.\n");
if (i != node_count)
TPRINTF("Bad node count. Some nodes have been lost!\n");
TPRINTF("done.\n");
}
 
char *test_avltree1(bool quiet)
char *test_avltree1(void)
{
alloc_avltree_node_prepare();
test_tree_insert(&avltree, NODE_COUNT, quiet);
test_tree_delete(&avltree, NODE_COUNT, 0, quiet);
 
test_tree_insert(&avltree, NODE_COUNT);
test_tree_delete(&avltree, NODE_COUNT, 0);
alloc_avltree_node_prepare();
test_tree_insert(&avltree, NODE_COUNT, quiet);
test_tree_delete(&avltree, NODE_COUNT, 1, quiet);
 
test_tree_insert(&avltree, NODE_COUNT);
test_tree_delete(&avltree, NODE_COUNT, 1);
alloc_avltree_node_prepare();
test_tree_insert(&avltree, NODE_COUNT, quiet);
test_tree_delmin(&avltree, NODE_COUNT, quiet);
 
test_tree_insert(&avltree, NODE_COUNT);
test_tree_delmin(&avltree, NODE_COUNT);
return NULL;
}
 
/branches/arm/kernel/test/avltree/avltree1.def
1,6 → 1,6
{
"avltree1",
"Test Avl tree operations",
"Test AVL tree operations",
&test_avltree1,
true
},
/branches/arm/kernel/test/synch/rwlock4.c
40,13 → 40,12
#include <synch/synch.h>
#include <synch/spinlock.h>
 
#define READERS 50
#define WRITERS 50
#define READERS 50
#define WRITERS 50
 
static atomic_t thread_count;
static rwlock_t rwlock;
static atomic_t threads_fault;
static bool sh_quiet;
 
SPINLOCK_INITIALIZE(rw_lock);
 
57,10 → 56,10
static uint32_t random(uint32_t max)
{
uint32_t rc;
 
spinlock_lock(&rw_lock);
spinlock_lock(&rw_lock);
rc = seed % max;
seed = (((seed<<2) ^ (seed>>2)) * 487) + rc;
seed = (((seed << 2) ^ (seed >> 2)) * 487) + rc;
spinlock_unlock(&rw_lock);
return rc;
}
70,43 → 69,39
int rc, to;
thread_detach(THREAD);
waitq_sleep(&can_start);
 
to = random(40000);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " w+ (%d)\n", CPU->id, THREAD->tid, to);
TPRINTF("cpu%u, tid %" PRIu64 " w+ (%d)\n", CPU->id, THREAD->tid, to);
rc = rwlock_write_lock_timeout(&rwlock, to);
if (SYNCH_FAILED(rc)) {
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " w!\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " w!\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
return;
}
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " w=\n", CPU->id, THREAD->tid);
 
TPRINTF("cpu%u, tid %" PRIu64 " w=\n", CPU->id, THREAD->tid);
if (rwlock.readers_in) {
if (!sh_quiet)
printf("Oops.");
TPRINTF("Oops.\n");
atomic_inc(&threads_fault);
atomic_dec(&thread_count);
return;
}
thread_usleep(random(1000000));
if (rwlock.readers_in) {
if (!sh_quiet)
printf("Oops.");
TPRINTF("Oops.\n");
atomic_inc(&threads_fault);
atomic_dec(&thread_count);
return;
}
 
rwlock_write_unlock(&rwlock);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " w-\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " w-\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
}
 
118,33 → 113,28
to = random(2000);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " r+ (%d)\n", CPU->id, THREAD->tid, to);
TPRINTF("cpu%u, tid %" PRIu64 " r+ (%d)\n", CPU->id, THREAD->tid, to);
rc = rwlock_read_lock_timeout(&rwlock, to);
if (SYNCH_FAILED(rc)) {
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " r!\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " r!\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
return;
}
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " r=\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " r=\n", CPU->id, THREAD->tid);
thread_usleep(30000);
rwlock_read_unlock(&rwlock);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 " r-\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " r-\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
}
 
char * test_rwlock4(bool quiet)
char *test_rwlock4(void)
{
context_t ctx;
uint32_t i;
sh_quiet = quiet;
waitq_initialize(&can_start);
rwlock_initialize(&rwlock);
158,28 → 148,25
thread_t *thrd;
context_save(&ctx);
if (!quiet) {
printf("sp=%#x, readers_in=%" PRIc "\n", ctx.sp, rwlock.readers_in);
printf("Creating %" PRIu32 " readers\n", rd);
}
TPRINTF("sp=%#x, readers_in=%" PRIs "\n", ctx.sp, rwlock.readers_in);
TPRINTF("Creating %" PRIu32 " readers\n", rd);
for (i = 0; i < rd; i++) {
thrd = thread_create(reader, NULL, TASK, 0, "reader", false);
if (thrd)
thread_ready(thrd);
else if (!quiet)
printf("Could not create reader %" PRIu32 "\n", i);
else
TPRINTF("Could not create reader %" PRIu32 "\n", i);
}
 
if (!quiet)
printf("Creating %" PRIu32 " writers\n", wr);
TPRINTF("Creating %" PRIu32 " writers\n", wr);
for (i = 0; i < wr; i++) {
thrd = thread_create(writer, NULL, TASK, 0, "writer", false);
if (thrd)
thread_ready(thrd);
else if (!quiet)
printf("Could not create writer %" PRIu32 "\n", i);
else
TPRINTF("Could not create writer %" PRIu32 "\n", i);
}
thread_usleep(20000);
186,8 → 173,7
waitq_wakeup(&can_start, WAKEUP_ALL);
while (atomic_get(&thread_count) > 0) {
if (!quiet)
printf("Threads left: %ld\n", atomic_get(&thread_count));
TPRINTF("Threads left: %ld\n", atomic_get(&thread_count));
thread_sleep(1);
}
/branches/arm/kernel/test/synch/rwlock1.c
35,39 → 35,39
#include <synch/waitq.h>
#include <synch/rwlock.h>
 
#define READERS 50
#define WRITERS 50
#define READERS 50
#define WRITERS 50
 
static rwlock_t rwlock;
 
char * test_rwlock1(bool quiet)
char *test_rwlock1(void)
{
rwlock_initialize(&rwlock);
 
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
 
rwlock_write_unlock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
 
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
 
rwlock_write_unlock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
 
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
 
rwlock_write_unlock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
/branches/arm/kernel/test/synch/rwlock2.c
34,38 → 34,34
 
#include <synch/rwlock.h>
 
#define READERS 50
#define WRITERS 50
#define READERS 50
#define WRITERS 50
 
static rwlock_t rwlock;
static bool sh_quiet;
 
static void writer(void *arg)
{
if (!sh_quiet)
printf("Trying to lock rwlock for writing....\n");
TPRINTF("Trying to lock rwlock for writing....\n");
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
if (!sh_quiet)
printf("Trying to lock rwlock for reading....\n");
TPRINTF("Trying to lock rwlock for reading....\n");
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
rwlock_read_unlock(&rwlock);
}
 
char * test_rwlock2(bool quiet)
char *test_rwlock2(void)
{
thread_t *thrd;
sh_quiet = quiet;
rwlock_initialize(&rwlock);
 
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
rwlock_read_lock(&rwlock);
thrd = thread_create(writer, NULL, TASK, 0, "writer", false);
if (thrd)
72,7 → 68,7
thread_ready(thrd);
else
return "Could not create thread";
 
thread_sleep(1);
rwlock_read_unlock(&rwlock);
/branches/arm/kernel/test/synch/rwlock3.c
34,41 → 34,35
 
#include <synch/rwlock.h>
 
#define THREADS 4
#define THREADS 4
 
static atomic_t thread_count;
static rwlock_t rwlock;
static bool sh_quiet;
 
static void reader(void *arg)
{
thread_detach(THREAD);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 ": trying to lock rwlock for reading....\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 ": trying to lock rwlock for reading....\n", CPU->id, THREAD->tid);
rwlock_read_lock(&rwlock);
rwlock_read_unlock(&rwlock);
if (!sh_quiet) {
printf("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid);
printf("cpu%u, tid %" PRIu64 ": trying to lock rwlock for writing....\n", CPU->id, THREAD->tid);
}
 
TPRINTF("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 ": trying to lock rwlock for writing....\n", CPU->id, THREAD->tid);
rwlock_write_lock(&rwlock);
rwlock_write_unlock(&rwlock);
if (!sh_quiet)
printf("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid);
atomic_dec(&thread_count);
}
 
char * test_rwlock3(bool quiet)
char *test_rwlock3(void)
{
int i;
thread_t *thrd;
sh_quiet = quiet;
atomic_set(&thread_count, THREADS);
79,16 → 73,15
thrd = thread_create(reader, NULL, TASK, 0, "reader", false);
if (thrd)
thread_ready(thrd);
else if (!quiet)
printf("Could not create reader %d\n", i);
else
TPRINTF("Could not create reader %d\n", i);
}
 
thread_sleep(1);
rwlock_write_unlock(&rwlock);
while (atomic_get(&thread_count) > 0) {
if (!quiet)
printf("Threads left: %ld\n", atomic_get(&thread_count));
TPRINTF("Threads left: %ld\n", atomic_get(&thread_count));
thread_sleep(1);
}
/branches/arm/kernel/test/synch/semaphore1.c
35,9 → 35,9
#include <synch/waitq.h>
#include <synch/semaphore.h>
 
#define AT_ONCE 3
#define PRODUCERS 50
#define CONSUMERS 50
#define AT_ONCE 3
#define PRODUCERS 50
#define CONSUMERS 50
 
static semaphore_t sem;
 
47,10 → 47,10
 
static void producer(void *arg)
{
thread_detach(THREAD);
 
thread_detach(THREAD);
waitq_sleep(&can_start);
semaphore_down(&sem);
atomic_inc(&items_produced);
thread_usleep(250);
59,7 → 59,7
 
static void consumer(void *arg)
{
thread_detach(THREAD);
thread_detach(THREAD);
waitq_sleep(&can_start);
69,7 → 69,7
semaphore_up(&sem);
}
 
char * test_semaphore1(bool quiet)
char *test_semaphore1(void)
{
int i, j, k;
int consumers, producers;
76,10 → 76,10
waitq_initialize(&can_start);
semaphore_initialize(&sem, AT_ONCE);
 
for (i = 1; i <= 3; i++) {
thread_t *thrd;
 
atomic_set(&items_produced, 0);
atomic_set(&items_consumed, 0);
86,8 → 86,8
consumers = i * CONSUMERS;
producers = (4 - i) * PRODUCERS;
printf("Creating %d consumers and %d producers...", consumers, producers);
TPRINTF("Creating %d consumers and %d producers...", consumers, producers);
for (j = 0; j < (CONSUMERS + PRODUCERS) / 2; j++) {
for (k = 0; k < i; k++) {
thrd = thread_create(consumer, NULL, TASK, 0, "consumer", false);
94,7 → 94,7
if (thrd)
thread_ready(thrd);
else
printf("could not create consumer %d\n", i);
TPRINTF("could not create consumer %d\n", i);
}
for (k = 0; k < (4 - i); k++) {
thrd = thread_create(producer, NULL, TASK, 0, "producer", false);
101,17 → 101,17
if (thrd)
thread_ready(thrd);
else
printf("could not create producer %d\n", i);
TPRINTF("could not create producer %d\n", i);
}
}
 
printf("ok\n");
 
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while ((items_consumed.count != consumers) || (items_produced.count != producers)) {
printf("%d consumers remaining, %d producers remaining\n", consumers - items_consumed.count, producers - items_produced.count);
TPRINTF("%d consumers remaining, %d producers remaining\n", consumers - items_consumed.count, producers - items_produced.count);
thread_sleep(1);
}
}
/branches/arm/kernel/test/synch/semaphore2.c
50,10 → 50,10
static uint32_t random(uint32_t max)
{
uint32_t rc;
 
spinlock_lock(&sem_lock);
spinlock_lock(&sem_lock);
rc = seed % max;
seed = (((seed<<2) ^ (seed>>2)) * 487) + rc;
seed = (((seed << 2) ^ (seed >> 2)) * 487) + rc;
spinlock_unlock(&sem_lock);
return rc;
}
67,21 → 67,21
waitq_sleep(&can_start);
to = random(20000);
printf("cpu%u, tid %" PRIu64 " down+ (%d)\n", CPU->id, THREAD->tid, to);
TPRINTF("cpu%u, tid %" PRIu64 " down+ (%d)\n", CPU->id, THREAD->tid, to);
rc = semaphore_down_timeout(&sem, to);
if (SYNCH_FAILED(rc)) {
printf("cpu%u, tid %" PRIu64 " down!\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " down!\n", CPU->id, THREAD->tid);
return;
}
printf("cpu%u, tid %" PRIu64 " down=\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " down=\n", CPU->id, THREAD->tid);
thread_usleep(random(30000));
semaphore_up(&sem);
printf("cpu%u, tid %" PRIu64 " up\n", CPU->id, THREAD->tid);
TPRINTF("cpu%u, tid %" PRIu64 " up\n", CPU->id, THREAD->tid);
}
 
char * test_semaphore2(bool quiet)
char *test_semaphore2(void)
{
uint32_t i, k;
91,13 → 91,13
thread_t *thrd;
k = random(7) + 1;
printf("Creating %" PRIu32 " consumers\n", k);
TPRINTF("Creating %" PRIu32 " consumers\n", k);
for (i = 0; i < k; i++) {
thrd = thread_create(consumer, NULL, TASK, 0, "consumer", false);
if (thrd)
thread_ready(thrd);
else
printf("Error creating thread\n");
TPRINTF("Error creating thread\n");
}
thread_usleep(20000);
/branches/arm/kernel/test/synch/rwlock5.c
35,8 → 35,8
#include <synch/waitq.h>
#include <synch/rwlock.h>
 
#define READERS 50
#define WRITERS 50
#define READERS 50
#define WRITERS 50
 
static rwlock_t rwlock;
 
47,9 → 47,9
static void writer(void *arg)
{
thread_detach(THREAD);
 
waitq_sleep(&can_start);
 
rwlock_write_lock(&rwlock);
atomic_inc(&items_written);
rwlock_write_unlock(&rwlock);
58,7 → 58,7
static void reader(void *arg)
{
thread_detach(THREAD);
 
waitq_sleep(&can_start);
rwlock_read_lock(&rwlock);
66,7 → 66,7
rwlock_read_unlock(&rwlock);
}
 
char * test_rwlock5(bool quiet)
char *test_rwlock5(void)
{
int i, j, k;
long readers, writers;
76,15 → 76,15
for (i = 1; i <= 3; i++) {
thread_t *thrd;
 
atomic_set(&items_read, 0);
atomic_set(&items_written, 0);
 
readers = i * READERS;
writers = (4 - i) * WRITERS;
 
printf("Creating %ld readers and %ld writers...", readers, writers);
TPRINTF("Creating %ld readers and %ld writers...", readers, writers);
for (j = 0; j < (READERS + WRITERS) / 2; j++) {
for (k = 0; k < i; k++) {
thrd = thread_create(reader, NULL, TASK, 0, "reader", false);
91,7 → 91,7
if (thrd)
thread_ready(thrd);
else
printf("Could not create reader %d\n", k);
TPRINTF("Could not create reader %d\n", k);
}
for (k = 0; k < (4 - i); k++) {
thrd = thread_create(writer, NULL, TASK, 0, "writer", false);
98,17 → 98,17
if (thrd)
thread_ready(thrd);
else
printf("Could not create writer %d\n", k);
TPRINTF("Could not create writer %d\n", k);
}
}
 
printf("ok\n");
 
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while ((items_read.count != readers) || (items_written.count != writers)) {
printf("%d readers remaining, %d writers remaining, readers_in=%d\n", readers - items_read.count, writers - items_written.count, rwlock.readers_in);
TPRINTF("%d readers remaining, %d writers remaining, readers_in=%d\n", readers - items_read.count, writers - items_written.count, rwlock.readers_in);
thread_usleep(100000);
}
}
/branches/arm/kernel/test/mm/falloc2.c
39,26 → 39,24
#include <memstr.h>
#include <arch.h>
 
#define MAX_FRAMES 256
#define MAX_ORDER 8
#define MAX_FRAMES 256
#define MAX_ORDER 8
 
#define THREAD_RUNS 1
#define THREADS 8
#define THREAD_RUNS 1
#define THREADS 8
 
static atomic_t thread_count;
static atomic_t thread_fail;
static bool sh_quiet;
 
static void falloc(void * arg)
static void falloc(void *arg)
{
int order, run, allocated, i;
uint8_t val = THREAD->tid % THREADS;
index_t k;
size_t k;
void **frames = (void **) malloc(MAX_FRAMES * sizeof(void *), FRAME_ATOMIC);
if (frames == NULL) {
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Unable to allocate frames\n", THREAD->tid, CPU->id);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Unable to allocate frames\n", THREAD->tid, CPU->id);
atomic_inc(&thread_fail);
atomic_dec(&thread_count);
return;
65,11 → 63,10
}
thread_detach(THREAD);
 
for (run = 0; run < THREAD_RUNS; run++) {
for (order = 0; order <= MAX_ORDER; order++) {
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order);
allocated = 0;
for (i = 0; i < (MAX_FRAMES >> order); i++) {
81,17 → 78,13
break;
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): %d blocks allocated.\n", THREAD->tid, CPU->id, allocated);
TPRINTF("Thread #%" PRIu64 " (cpu%u): %d blocks allocated.\n", THREAD->tid, CPU->id, allocated);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Deallocating ... \n", THREAD->tid, CPU->id);
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Deallocating ... \n", THREAD->tid, CPU->id);
for (i = 0; i < allocated; i++) {
for (k = 0; k <= (((index_t) FRAME_SIZE << order) - 1); k++) {
for (k = 0; k <= (((size_t) FRAME_SIZE << order) - 1); k++) {
if (((uint8_t *) frames[i])[k] != val) {
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Unexpected data (%c) in block %p offset %#" PRIi "\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Unexpected data (%c) in block %p offset %#" PRIs "\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k);
atomic_inc(&thread_fail);
goto cleanup;
}
99,32 → 92,28
frame_free(KA2PA(frames[i]));
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Finished run.\n", THREAD->tid, CPU->id);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Finished run.\n", THREAD->tid, CPU->id);
}
}
 
cleanup:
cleanup:
free(frames);
if (!sh_quiet)
printf("Thread #%" PRIu64 " (cpu%u): Exiting\n", THREAD->tid, CPU->id);
TPRINTF("Thread #%" PRIu64 " (cpu%u): Exiting\n", THREAD->tid, CPU->id);
atomic_dec(&thread_count);
}
 
char * test_falloc2(bool quiet)
char *test_falloc2(void)
{
unsigned int i;
sh_quiet = quiet;
 
atomic_set(&thread_count, THREADS);
atomic_set(&thread_fail, 0);
for (i = 0; i < THREADS; i++) {
thread_t * thrd = thread_create(falloc, NULL, TASK, 0, "falloc", false);
if (!thrd) {
if (!quiet)
printf("Could not create thread %u\n", i);
TPRINTF("Could not create thread %u\n", i);
break;
}
thread_ready(thrd);
131,8 → 120,7
}
while (atomic_get(&thread_count) > 0) {
if (!quiet)
printf("Threads left: %ld\n", atomic_get(&thread_count));
TPRINTF("Threads left: %ld\n", atomic_get(&thread_count));
thread_sleep(1);
}
/branches/arm/kernel/test/mm/purge1.c
26,8 → 26,6
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifdef ia64
 
#include <print.h>
#include <test.h>
#include <mm/page.h>
39,18 → 37,18
#include <debug.h>
 
extern void tlb_invalidate_all(void);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t va, count_t cnt);
extern void tlb_invalidate_pages(asid_t asid, uintptr_t va, size_t cnt);
 
char * test_purge1(bool quiet)
char *test_purge1(void)
{
tlb_entry_t entryi;
tlb_entry_t entryd;
int i;
entryd.word[0] = 0;
entryd.word[1] = 0;
entryd.p = true; /* present */
entryd.ma = MA_WRITEBACK;
entryd.a = true; /* already accessed */
77,11 → 75,9
dtc_mapping_insert(0 + i * (1 << PAGE_WIDTH), 9, entryd);
}
tlb_invalidate_pages(8,0x0c000,14);
tlb_invalidate_pages(8, 0x0c000, 14);
/*tlb_invalidate_all();*/
/* tlb_invalidate_all(); */
return NULL;
}
 
#endif
/branches/arm/kernel/test/mm/slab2.c
36,18 → 36,18
#include <synch/condvar.h>
#include <synch/mutex.h>
 
#define ITEM_SIZE 256
#define ITEM_SIZE 256
 
/** Fill memory with 2 caches, when allocation fails,
* free one of the caches. We should have everything in magazines,
* now allocation should clean magazines and allow for full allocation.
*/
static void totalmemtest(bool quiet)
static void totalmemtest(void)
{
slab_cache_t *cache1;
slab_cache_t *cache2;
int i;
 
void *data1, *data2;
void *olddata1 = NULL, *olddata2 = NULL;
54,8 → 54,7
cache1 = slab_cache_create("cache1_tst", ITEM_SIZE, 0, NULL, NULL, 0);
cache2 = slab_cache_create("cache2_tst", ITEM_SIZE, 0, NULL, NULL, 0);
if (!quiet)
printf("Allocating...");
TPRINTF("Allocating...");
/* Use atomic alloc, so that we find end of memory */
do {
74,13 → 73,12
*((void **) data2) = olddata2;
olddata1 = data1;
olddata2 = data2;
} while (1);
} while (true);
if (!quiet) {
printf("done.\n");
printf("Deallocating cache2...");
}
TPRINTF("done.\n");
TPRINTF("Deallocating cache2...");
/* We do not have memory - now deallocate cache2 */
while (olddata2) {
data2 = *((void **) olddata2);
88,16 → 86,14
olddata2 = data2;
}
if (!quiet) {
printf("done.\n");
printf("Allocating to cache1...\n");
}
TPRINTF("done.\n");
TPRINTF("Allocating to cache1...\n");
for (i = 0; i < 30; i++) {
data1 = slab_alloc(cache1, FRAME_ATOMIC);
if (!data1) {
if (!quiet)
printf("Incorrect memory size - use another test.");
TPRINTF("Incorrect memory size - use another test.");
return;
}
memsetb(data1, ITEM_SIZE, 0);
104,7 → 100,7
*((void **) data1) = olddata1;
olddata1 = data1;
}
while (1) {
while (true) {
data1 = slab_alloc(cache1, FRAME_ATOMIC);
if (!data1)
break;
113,8 → 109,7
olddata1 = data1;
}
if (!quiet)
printf("Deallocating cache1...");
TPRINTF("Deallocating cache1...");
while (olddata1) {
data1 = *((void **) olddata1);
122,10 → 117,10
olddata1 = data1;
}
if (!quiet) {
printf("done.\n");
TPRINTF("done.\n");
if (!test_quiet)
slab_print_list();
}
slab_cache_destroy(cache1);
slab_cache_destroy(cache2);
135,9 → 130,8
static semaphore_t thr_sem;
static condvar_t thread_starter;
static mutex_t starter_mutex;
static bool sh_quiet;
 
#define THREADS 8
#define THREADS 8
 
static void slabtest(void *priv)
{
149,14 → 143,12
condvar_wait(&thread_starter,&starter_mutex);
mutex_unlock(&starter_mutex);
if (!sh_quiet)
printf("Starting thread #%" PRIu64 "...\n", THREAD->tid);
TPRINTF("Starting thread #%" PRIu64 "...\n", THREAD->tid);
 
/* Alloc all */
if (!sh_quiet)
printf("Thread #%" PRIu64 " allocating...\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " allocating...\n", THREAD->tid);
while (1) {
while (true) {
/* Call with atomic to detect end of memory */
new = slab_alloc(thr_cache, FRAME_ATOMIC);
if (!new)
165,8 → 157,7
data = new;
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " releasing...\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " releasing...\n", THREAD->tid);
while (data) {
new = *((void **)data);
175,10 → 166,9
data = new;
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " allocating...\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " allocating...\n", THREAD->tid);
while (1) {
while (true) {
/* Call with atomic to detect end of memory */
new = slab_alloc(thr_cache, FRAME_ATOMIC);
if (!new)
187,8 → 177,7
data = new;
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " releasing...\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " releasing...\n", THREAD->tid);
while (data) {
new = *((void **)data);
197,14 → 186,15
data = new;
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " finished\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " finished\n", THREAD->tid);
slab_print_list();
if (!test_quiet)
slab_print_list();
semaphore_up(&thr_sem);
}
 
static void multitest(int size, bool quiet)
static void multitest(int size)
{
/* Start 8 threads that just allocate as much as possible,
* then release everything, then again allocate, then release
212,48 → 202,42
thread_t *t;
int i;
if (!quiet)
printf("Running stress test with size %d\n", size);
TPRINTF("Running stress test with size %d\n", size);
condvar_initialize(&thread_starter);
mutex_initialize(&starter_mutex, MUTEX_PASSIVE);
 
thr_cache = slab_cache_create("thread_cache", size, 0, NULL, NULL, 0);
semaphore_initialize(&thr_sem,0);
for (i = 0; i < THREADS; i++) {
if (!(t = thread_create(slabtest, NULL, TASK, 0, "slabtest", false))) {
if (!quiet)
printf("Could not create thread %d\n", i);
TPRINTF("Could not create thread %d\n", i);
} else
thread_ready(t);
}
thread_sleep(1);
condvar_broadcast(&thread_starter);
 
for (i = 0; i < THREADS; i++)
semaphore_down(&thr_sem);
slab_cache_destroy(thr_cache);
if (!quiet)
printf("Stress test complete.\n");
TPRINTF("Stress test complete.\n");
}
 
char * test_slab2(bool quiet)
char *test_slab2(void)
{
sh_quiet = quiet;
TPRINTF("Running reclaim single-thread test .. pass 1\n");
totalmemtest();
if (!quiet)
printf("Running reclaim single-thread test .. pass 1\n");
totalmemtest(quiet);
if (!quiet)
printf("Running reclaim single-thread test .. pass 2\n");
totalmemtest(quiet);
if (!quiet)
printf("Reclaim test OK.\n");
TPRINTF("Running reclaim single-thread test .. pass 2\n");
totalmemtest();
multitest(128, quiet);
multitest(2048, quiet);
multitest(8192, quiet);
TPRINTF("Reclaim test OK.\n");
multitest(128);
multitest(2048);
multitest(8192);
return NULL;
}
/branches/arm/kernel/test/mm/falloc1.c
36,12 → 36,13
#include <debug.h>
#include <align.h>
 
#define MAX_FRAMES 1024
#define MAX_ORDER 8
#define TEST_RUNS 2
#define MAX_FRAMES 1024
#define MAX_ORDER 8
#define TEST_RUNS 2
 
char * test_falloc1(bool quiet) {
uintptr_t * frames = (uintptr_t *) malloc(MAX_FRAMES * sizeof(uintptr_t), 0);
char *test_falloc1(void) {
uintptr_t *frames
= (uintptr_t *) malloc(MAX_FRAMES * sizeof(uintptr_t), 0);
int results[MAX_ORDER + 1];
int i, order, run;
52,11 → 53,10
if (frames == NULL)
return "Unable to allocate frames";
 
for (run = 0; run < TEST_RUNS; run++) {
for (order = 0; order <= MAX_ORDER; order++) {
if (!quiet)
printf("Allocating %d frames blocks ... ", 1 << order);
TPRINTF("Allocating %d frames blocks ... ", 1 << order);
allocated = 0;
for (i = 0; i < MAX_FRAMES >> order; i++) {
63,8 → 63,7
frames[allocated] = (uintptr_t) frame_alloc(order, FRAME_ATOMIC | FRAME_KA);
if (ALIGN_UP(frames[allocated], FRAME_SIZE << order) != frames[allocated]) {
if (!quiet)
printf("Block at address %p (size %dK) is not aligned\n", frames[allocated], (FRAME_SIZE << order) >> 10);
TPRINTF("Block at address %p (size %dK) is not aligned\n", frames[allocated], (FRAME_SIZE << order) >> 10);
return "Test failed";
}
71,15 → 70,13
if (frames[allocated])
allocated++;
else {
if (!quiet)
printf("done. ");
TPRINTF("done. ");
break;
}
}
if (!quiet)
printf("%d blocks allocated.\n", allocated);
TPRINTF("%d blocks allocated.\n", allocated);
if (run) {
if (results[order] != allocated)
return "Possible frame leak";
86,17 → 83,15
} else
results[order] = allocated;
if (!quiet)
printf("Deallocating ... ");
TPRINTF("Deallocating ... ");
for (i = 0; i < allocated; i++)
frame_free(KA2PA(frames[i]));
if (!quiet)
printf("done.\n");
TPRINTF("done.\n");
}
}
 
free(frames);
return NULL;
/branches/arm/kernel/test/mm/slab1.c
33,23 → 33,21
#include <arch.h>
#include <memstr.h>
 
#define VAL_COUNT 1024
#define VAL_COUNT 1024
 
static void * data[VAL_COUNT];
static void *data[VAL_COUNT];
 
static void testit(int size, int count, bool quiet)
static void testit(int size, int count)
{
slab_cache_t *cache;
int i;
if (!quiet)
printf("Creating cache, object size: %d.\n", size);
TPRINTF("Creating cache, object size: %d.\n", size);
cache = slab_cache_create("test_cache", size, 0, NULL, NULL,
SLAB_CACHE_NOMAGAZINE);
SLAB_CACHE_NOMAGAZINE);
if (!quiet)
printf("Allocating %d items...", count);
TPRINTF("Allocating %d items...", count);
for (i = 0; i < count; i++) {
data[i] = slab_alloc(cache, 0);
56,78 → 54,71
memsetb(data[i], size, 0);
}
if (!quiet) {
printf("done.\n");
printf("Freeing %d items...", count);
}
TPRINTF("done.\n");
TPRINTF("Freeing %d items...", count);
for (i = 0; i < count; i++)
slab_free(cache, data[i]);
if (!quiet) {
printf("done.\n");
printf("Allocating %d items...", count);
}
TPRINTF("done.\n");
TPRINTF("Allocating %d items...", count);
for (i = 0; i < count; i++) {
data[i] = slab_alloc(cache, 0);
memsetb(data[i], size, 0);
}
if (!quiet) {
printf("done.\n");
printf("Freeing %d items...", count / 2);
}
TPRINTF("done.\n");
TPRINTF("Freeing %d items...", count / 2);
for (i = count - 1; i >= count / 2; i--)
slab_free(cache, data[i]);
if (!quiet) {
printf("done.\n");
printf("Allocating %d items...", count / 2);
}
TPRINTF("done.\n");
TPRINTF("Allocating %d items...", count / 2);
for (i = count / 2; i < count; i++) {
data[i] = slab_alloc(cache, 0);
memsetb(data[i], size, 0);
}
if (!quiet) {
printf("done.\n");
printf("Freeing %d items...", count);
}
TPRINTF("done.\n");
TPRINTF("Freeing %d items...", count);
for (i = 0; i < count; i++)
slab_free(cache, data[i]);
if (!quiet)
printf("done.\n");
TPRINTF("done.\n");
slab_cache_destroy(cache);
if (!quiet)
printf("Test complete.\n");
TPRINTF("Test complete.\n");
}
 
static void testsimple(bool quiet)
static void testsimple(void)
{
testit(100, VAL_COUNT, quiet);
testit(200, VAL_COUNT, quiet);
testit(1024, VAL_COUNT, quiet);
testit(2048, 512, quiet);
testit(4000, 128, quiet);
testit(8192, 128, quiet);
testit(16384, 128, quiet);
testit(16385, 128, quiet);
testit(100, VAL_COUNT);
testit(200, VAL_COUNT);
testit(1024, VAL_COUNT);
testit(2048, 512);
testit(4000, 128);
testit(8192, 128);
testit(16384, 128);
testit(16385, 128);
}
 
#define THREADS 6
#define THR_MEM_COUNT 1024
#define THR_MEM_SIZE 128
#define THREADS 6
#define THR_MEM_COUNT 1024
#define THR_MEM_SIZE 128
 
static void * thr_data[THREADS][THR_MEM_COUNT];
static void *thr_data[THREADS][THR_MEM_COUNT];
static slab_cache_t *thr_cache;
static semaphore_t thr_sem;
static bool sh_quiet;
 
static void slabtest(void *data)
{
136,8 → 127,7
thread_detach(THREAD);
if (!sh_quiet)
printf("Starting thread #%" PRIu64 "...\n", THREAD->tid);
TPRINTF("Starting thread #%" PRIu64 "...\n", THREAD->tid);
for (j = 0; j < 10; j++) {
for (i = 0; i < THR_MEM_COUNT; i++)
150,24 → 140,23
slab_free(thr_cache, thr_data[offs][i]);
}
if (!sh_quiet)
printf("Thread #%" PRIu64 " finished\n", THREAD->tid);
TPRINTF("Thread #%" PRIu64 " finished\n", THREAD->tid);
semaphore_up(&thr_sem);
}
 
static void testthreads(bool quiet)
static void testthreads(void)
{
thread_t *t;
int i;
 
thr_cache = slab_cache_create("thread_cache", THR_MEM_SIZE, 0, NULL, NULL,
SLAB_CACHE_NOMAGAZINE);
SLAB_CACHE_NOMAGAZINE);
semaphore_initialize(&thr_sem, 0);
for (i = 0; i < THREADS; i++) {
if (!(t = thread_create(slabtest, (void *) (unative_t) i, TASK, 0, "slabtest", false))) {
if (!quiet)
printf("Could not create thread %d\n", i);
TPRINTF("Could not create thread %d\n", i);
} else
thread_ready(t);
}
177,16 → 166,13
slab_cache_destroy(thr_cache);
if (!quiet)
printf("Test complete.\n");
TPRINTF("Test complete.\n");
}
 
char * test_slab1(bool quiet)
char *test_slab1(void)
{
sh_quiet = quiet;
testsimple();
testthreads();
testsimple(quiet);
testthreads(quiet);
return NULL;
}
/branches/arm/kernel/test/mm/purge1_skip.c
0,0 → 1,34
/*
* Copyright (c) 2009 Martin Decky
* 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.
*/
 
#include <test.h>
 
char *test_purge1(void)
{
return NULL;
}
/branches/arm/kernel/test/mm/mapping1.c
35,40 → 35,36
#include <arch/types.h>
#include <debug.h>
 
#define PAGE0 0x10000000
#define PAGE1 (PAGE0+PAGE_SIZE)
#define PAGE0 0x10000000
#define PAGE1 (PAGE0 + PAGE_SIZE)
 
#define VALUE0 0x01234567
#define VALUE1 0x89abcdef
#define VALUE0 0x01234567
#define VALUE1 0x89abcdef
 
char * test_mapping1(bool quiet)
char *test_mapping1(void)
{
uintptr_t frame0, frame1;
uint32_t v0, v1;
 
frame0 = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_KA);
frame1 = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_KA);
if (!quiet)
printf("Writing %#x to physical address %p.\n", VALUE0, KA2PA(frame0));
TPRINTF("Writing %#x to physical address %p.\n", VALUE0, KA2PA(frame0));
*((uint32_t *) frame0) = VALUE0;
if (!quiet)
printf("Writing %#x to physical address %p.\n", VALUE1, KA2PA(frame1));
TPRINTF("Writing %#x to physical address %p.\n", VALUE1, KA2PA(frame1));
*((uint32_t *) frame1) = VALUE1;
if (!quiet)
printf("Mapping virtual address %p to physical address %p.\n", PAGE0, KA2PA(frame0));
TPRINTF("Mapping virtual address %p to physical address %p.\n", PAGE0, KA2PA(frame0));
page_mapping_insert(AS_KERNEL, PAGE0, KA2PA(frame0), PAGE_PRESENT | PAGE_WRITE);
if (!quiet)
printf("Mapping virtual address %p to physical address %p.\n", PAGE1, KA2PA(frame1));
TPRINTF("Mapping virtual address %p to physical address %p.\n", PAGE1, KA2PA(frame1));
page_mapping_insert(AS_KERNEL, PAGE1, KA2PA(frame1), PAGE_PRESENT | PAGE_WRITE);
v0 = *((uint32_t *) PAGE0);
v1 = *((uint32_t *) PAGE1);
if (!quiet) {
printf("Value at virtual address %p is %#x.\n", PAGE0, v0);
printf("Value at virtual address %p is %#x.\n", PAGE1, v1);
}
TPRINTF("Value at virtual address %p is %#x.\n", PAGE0, v0);
TPRINTF("Value at virtual address %p is %#x.\n", PAGE1, v1);
if (v0 != VALUE0)
return "Value at v0 not equal to VALUE0";
75,25 → 71,22
if (v1 != VALUE1)
return "Value at v1 not equal to VALUE1";
if (!quiet)
printf("Writing %#x to virtual address %p.\n", 0, PAGE0);
TPRINTF("Writing %#x to virtual address %p.\n", 0, PAGE0);
*((uint32_t *) PAGE0) = 0;
if (!quiet)
printf("Writing %#x to virtual address %p.\n", 0, PAGE1);
*((uint32_t *) PAGE1) = 0;
 
TPRINTF("Writing %#x to virtual address %p.\n", 0, PAGE1);
*((uint32_t *) PAGE1) = 0;
v0 = *((uint32_t *) PAGE0);
v1 = *((uint32_t *) PAGE1);
if (!quiet) {
printf("Value at virtual address %p is %#x.\n", PAGE0, *((uint32_t *) PAGE0));
printf("Value at virtual address %p is %#x.\n", PAGE1, *((uint32_t *) PAGE1));
}
 
TPRINTF("Value at virtual address %p is %#x.\n", PAGE0, *((uint32_t *) PAGE0));
TPRINTF("Value at virtual address %p is %#x.\n", PAGE1, *((uint32_t *) PAGE1));
if (v0 != 0)
return "Value at v0 not equal to 0";
if (v1 != 0)
return "Value at v1 not equal to 0";
return NULL;
return NULL;
}
/branches/arm/kernel/test/mm/purge1.def
1,4 → 1,3
#ifdef ia64
{
"purge1",
"Itanium TLB purge test",
5,4 → 4,3
&test_purge1,
true
},
#endif
/branches/arm/kernel/test/test.c
34,6 → 34,8
 
#include <test.h>
 
bool test_quiet;
 
test_t tests[] = {
#include <atomic/atomic1.def>
#include <avltree/avltree1.def>
56,11 → 58,14
#include <synch/semaphore1.def>
#include <synch/semaphore2.def>
#include <print/print1.def>
#include <print/print2.def>
#include <print/print3.def>
#include <print/print4.def>
#include <thread/thread1.def>
#include <sysinfo/sysinfo1.def>
{
.name = NULL,
.desc = NULL,
.desc = NULL,
.entry = NULL
}
};
/branches/arm/kernel/test/btree/btree1.c
33,15 → 33,14
 
static void *data = (void *) 0xdeadbeef;
 
char * test_btree1(bool quiet)
char *test_btree1(void)
{
btree_t t;
int i;
 
btree_create(&t);
if (!quiet)
printf("Inserting keys.\n");
TPRINTF("Inserting keys.\n");
btree_insert(&t, 19, data, NULL);
btree_insert(&t, 20, data, NULL);
btree_insert(&t, 21, data, NULL);
78,11 → 77,10
for (i = 100; i >= 50; i--)
btree_insert(&t, i, data, NULL);
if (!quiet)
if (!test_quiet)
btree_print(&t);
if (!quiet)
printf("Removing keys.\n");
TPRINTF("Removing keys.\n");
btree_remove(&t, 50, NULL);
btree_remove(&t, 49, NULL);
btree_remove(&t, 51, NULL);
158,7 → 156,7
btree_remove(&t, 35, NULL);
btree_remove(&t, 36, NULL);
if (!quiet)
if (!test_quiet)
btree_print(&t);
return NULL;
/branches/arm/kernel/test/test.h
38,8 → 38,17
#include <arch/types.h>
#include <typedefs.h>
 
typedef char *(*test_entry_t)(bool);
extern bool test_quiet;
 
#define TPRINTF(format, ...) \
{ \
if (!test_quiet) { \
printf(format, ##__VA_ARGS__); \
} \
}
 
typedef char *(*test_entry_t)(void);
 
typedef struct {
char *name;
char *desc;
47,30 → 56,33
bool safe;
} test_t;
 
extern char * test_atomic1(bool quiet);
extern char * test_avltree1(bool quiet);
extern char * test_btree1(bool quiet);
extern char * test_mips1(bool quiet);
extern char * test_fault1(bool quiet);
extern char * test_fpu1(bool quiet);
extern char * test_sse1(bool quiet);
extern char * test_mips2(bool quiet);
extern char * test_falloc1(bool quiet);
extern char * test_falloc2(bool quiet);
extern char * test_mapping1(bool quiet);
extern char * test_purge1(bool quiet);
extern char * test_slab1(bool quiet);
extern char * test_slab2(bool quiet);
extern char * test_rwlock1(bool quiet);
extern char * test_rwlock2(bool quiet);
extern char * test_rwlock3(bool quiet);
extern char * test_rwlock4(bool quiet);
extern char * test_rwlock5(bool quiet);
extern char * test_semaphore1(bool quiet);
extern char * test_semaphore2(bool quiet);
extern char * test_print1(bool quiet);
extern char * test_thread1(bool quiet);
extern char * test_sysinfo1(bool quiet);
extern char *test_atomic1(void);
extern char *test_avltree1(void);
extern char *test_btree1(void);
extern char *test_mips1(void);
extern char *test_fault1(void);
extern char *test_fpu1(void);
extern char *test_sse1(void);
extern char *test_mips2(void);
extern char *test_falloc1(void);
extern char *test_falloc2(void);
extern char *test_mapping1(void);
extern char *test_purge1(void);
extern char *test_slab1(void);
extern char *test_slab2(void);
extern char *test_rwlock1(void);
extern char *test_rwlock2(void);
extern char *test_rwlock3(void);
extern char *test_rwlock4(void);
extern char *test_rwlock5(void);
extern char *test_semaphore1(void);
extern char *test_semaphore2(void);
extern char *test_print1(void);
extern char *test_print2(void);
extern char *test_print3(void);
extern char *test_print4(void);
extern char *test_thread1(void);
extern char *test_sysinfo1(void);
 
extern test_t tests[];
 
/branches/arm/kernel/test/debug/mips1_skip.c
0,0 → 1,34
/*
* Copyright (c) 2009 Martin Decky
* 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.
*/
 
#include <test.h>
 
char *test_mips1(void)
{
return NULL;
}
/branches/arm/kernel/test/debug/mips1.c
25,8 → 25,6
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef mips32
 
#include <print.h>
#include <debug.h>
38,10 → 36,9
 
#include <arch.h>
 
char * test_mips1(bool quiet)
char *test_mips1(void)
{
if (!quiet)
printf("You should enter kconsole debug mode now.\n");
TPRINTF("If kconsole is compiled in, you should enter debug mode now.\n");
asm volatile (
"break\n"
49,5 → 46,3
return "Back from debug mode";
}
 
#endif
/branches/arm/kernel/test/debug/mips1.def
1,4 → 1,3
#ifdef mips32
{
"mips1",
"MIPS debug test",
5,4 → 4,3
&test_mips1,
false
},
#endif
/branches/arm/kernel/test/thread/thread1.c
36,37 → 36,33
 
#include <arch.h>
 
#define THREADS 5
#define THREADS 5
 
static atomic_t finish;
static atomic_t threads_finished;
static bool sh_quiet;
 
static void threadtest(void *data)
{
thread_detach(THREAD);
 
thread_detach(THREAD);
while (atomic_get(&finish)) {
if (!sh_quiet)
printf("%" PRIu64 " ", THREAD->tid);
TPRINTF("%" PRIu64 " ", THREAD->tid);
thread_usleep(100000);
}
atomic_inc(&threads_finished);
}
 
char * test_thread1(bool quiet)
char *test_thread1(void)
{
unsigned int i, total = 0;
sh_quiet = quiet;
atomic_set(&finish, 1);
atomic_set(&threads_finished, 0);
 
for (i = 0; i < THREADS; i++) {
thread_t *t;
if (!(t = thread_create(threadtest, NULL, TASK, 0, "threadtest", false))) {
if (!quiet)
printf("Could not create thread %d\n", i);
TPRINTF("Could not create thread %d\n", i);
break;
}
thread_ready(t);
73,14 → 69,12
total++;
}
if (!quiet)
printf("Running threads for 10 seconds...\n");
TPRINTF("Running threads for 10 seconds...\n");
thread_sleep(10);
atomic_set(&finish, 0);
while (atomic_get(&threads_finished) < ((long) total)) {
if (!quiet)
printf("Threads left: %d\n", total - atomic_get(&threads_finished));
TPRINTF("Threads left: %d\n", total - atomic_get(&threads_finished));
thread_sleep(1);
}
/branches/arm/kernel/test/fpu/fpu1.c
File deleted
/branches/arm/kernel/test/fpu/fpu1_ia64.c
0,0 → 1,170
/*
* Copyright (c) 2005 Jakub Vana
* Copyright (c) 2005 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.
*/
 
#include <print.h>
#include <debug.h>
 
#include <test.h>
#include <atomic.h>
#include <proc/thread.h>
 
#include <arch.h>
#include <arch/arch.h>
 
 
#define THREADS 150
#define ATTEMPTS 100
 
#define E_10e8 271828182
#define PI_10e8 3141592
 
static inline long double sqrt(long double a)
{
long double x = 1;
long double lx = 0;
if (a < 0.00000000000000001)
return 0;
while (x != lx) {
lx = x;
x = (x + (a / x)) / 2;
}
return x;
}
 
static atomic_t threads_ok;
static atomic_t threads_fault;
static waitq_t can_start;
 
static void e(void *data)
{
int i;
double e, d, le, f;
thread_detach(THREAD);
waitq_sleep(&can_start);
for (i = 0; i<ATTEMPTS; i++) {
le = -1;
e = 0;
f = 1;
for (d = 1; e != le; d *= f, f += 1) {
le = e;
e = e + 1 / d;
}
if ((int) (100000000 * e) != E_10e8) {
TPRINTF("tid%" PRIu64 ": e*10e8=%zd should be %" PRIun "\n", THREAD->tid, (unative_t) (100000000 * e), (unative_t) E_10e8);
atomic_inc(&threads_fault);
break;
}
}
atomic_inc(&threads_ok);
}
 
static void pi(void *data)
{
int i;
double lpi, pi;
double n, ab, ad;
thread_detach(THREAD);
waitq_sleep(&can_start);
for (i = 0; i < ATTEMPTS; i++) {
lpi = -1;
pi = 0;
for (n = 2, ab = sqrt(2); lpi != pi; n *= 2, ab = ad) {
double sc, cd;
sc = sqrt(1 - (ab * ab / 4));
cd = 1 - sc;
ad = sqrt(ab * ab / 4 + cd * cd);
lpi = pi;
pi = 2 * n * ad;
}
if ((int) (1000000 * pi) != PI_10e8) {
TPRINTF("tid%" PRIu64 ": pi*10e8=%zd should be %" PRIun "\n", THREAD->tid, (unative_t) (1000000 * pi), (unative_t) (PI_10e8 / 100));
atomic_inc(&threads_fault);
break;
}
}
atomic_inc(&threads_ok);
}
 
char *test_fpu1(void)
{
unsigned int i, total = 0;
waitq_initialize(&can_start);
atomic_set(&threads_ok, 0);
atomic_set(&threads_fault, 0);
TPRINTF("Creating %u threads... ", 2 * THREADS);
for (i = 0; i < THREADS; i++) {
thread_t *t;
if (!(t = thread_create(e, NULL, TASK, 0, "e", false))) {
TPRINTF("could not create thread %u\n", 2 * i);
break;
}
thread_ready(t);
total++;
if (!(t = thread_create(pi, NULL, TASK, 0, "pi", false))) {
TPRINTF("could not create thread %u\n", 2 * i + 1);
break;
}
thread_ready(t);
total++;
}
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while (atomic_get(&threads_ok) != (long) total) {
TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
thread_sleep(1);
}
if (atomic_get(&threads_fault) == 0)
return NULL;
return "Test failed";
}
/branches/arm/kernel/test/fpu/fpu1_x86.c
0,0 → 1,167
/*
* Copyright (c) 2005 Jakub Vana
* Copyright (c) 2005 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.
*/
 
#include <print.h>
#include <debug.h>
 
#include <test.h>
#include <atomic.h>
#include <proc/thread.h>
 
#include <arch.h>
#include <arch/arch.h>
 
 
#define THREADS 150
#define ATTEMPTS 100
 
#define E_10e8 271828182
#define PI_10e8 314159265
 
static inline double sqrt(double x)
{
double v;
asm (
"fsqrt\n"
: "=t" (v)
: "0" (x)
);
return v;
}
 
static atomic_t threads_ok;
static atomic_t threads_fault;
static waitq_t can_start;
 
static void e(void *data)
{
int i;
double e, d, le, f;
thread_detach(THREAD);
waitq_sleep(&can_start);
for (i = 0; i<ATTEMPTS; i++) {
le = -1;
e = 0;
f = 1;
for (d = 1; e != le; d *= f, f += 1) {
le = e;
e = e + 1 / d;
}
if ((int) (100000000 * e) != E_10e8) {
TPRINTF("tid%" PRIu64 ": e*10e8=%zd should be %" PRIun "\n", THREAD->tid, (unative_t) (100000000 * e), (unative_t) E_10e8);
atomic_inc(&threads_fault);
break;
}
}
atomic_inc(&threads_ok);
}
 
static void pi(void *data)
{
int i;
double lpi, pi;
double n, ab, ad;
thread_detach(THREAD);
waitq_sleep(&can_start);
for (i = 0; i < ATTEMPTS; i++) {
lpi = -1;
pi = 0;
for (n = 2, ab = sqrt(2); lpi != pi; n *= 2, ab = ad) {
double sc, cd;
sc = sqrt(1 - (ab * ab / 4));
cd = 1 - sc;
ad = sqrt(ab * ab / 4 + cd * cd);
lpi = pi;
pi = 2 * n * ad;
}
if ((int) (100000000 * pi) != PI_10e8) {
TPRINTF("tid%" PRIu64 ": pi*10e8=%zd should be %" PRIun "\n", THREAD->tid, (unative_t) (100000000 * pi), (unative_t) PI_10e8);
atomic_inc(&threads_fault);
break;
}
}
atomic_inc(&threads_ok);
}
 
char *test_fpu1(void)
{
unsigned int i, total = 0;
waitq_initialize(&can_start);
atomic_set(&threads_ok, 0);
atomic_set(&threads_fault, 0);
TPRINTF("Creating %u threads... ", 2 * THREADS);
for (i = 0; i < THREADS; i++) {
thread_t *t;
if (!(t = thread_create(e, NULL, TASK, 0, "e", false))) {
TPRINTF("could not create thread %u\n", 2 * i);
break;
}
thread_ready(t);
total++;
if (!(t = thread_create(pi, NULL, TASK, 0, "pi", false))) {
TPRINTF("could not create thread %u\n", 2 * i + 1);
break;
}
thread_ready(t);
total++;
}
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while (atomic_get(&threads_ok) != (long) total) {
TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
thread_sleep(1);
}
if (atomic_get(&threads_fault) == 0)
return NULL;
return "Test failed";
}
/branches/arm/kernel/test/fpu/mips2_skip.c
0,0 → 1,34
/*
* Copyright (c) 2009 Martin Decky
* 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.
*/
 
#include <test.h>
 
char *test_mips2(void)
{
return NULL;
}
/branches/arm/kernel/test/fpu/fpu1_skip.c
0,0 → 1,34
/*
* Copyright (c) 2009 Martin Decky
* 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.
*/
 
#include <test.h>
 
char *test_fpu1(void)
{
return NULL;
}
/branches/arm/kernel/test/fpu/sse1_skip.c
0,0 → 1,34
/*
* Copyright (c) 2009 Martin Decky
* 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.
*/
 
#include <test.h>
 
char *test_sse1(void)
{
return NULL;
}
/branches/arm/kernel/test/fpu/mips2.c
26,8 → 26,6
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifdef mips32
 
#include <print.h>
#include <debug.h>
 
38,14 → 36,13
 
#include <arch.h>
 
#define THREADS 50
#define DELAY 10000L
#define ATTEMPTS 5
#define THREADS 50
#define DELAY 10000L
#define ATTEMPTS 5
 
static atomic_t threads_ok;
static atomic_t threads_fault;
static waitq_t can_start;
static bool sh_quiet;
 
static void testit1(void *data)
{
56,7 → 53,7
thread_detach(THREAD);
waitq_sleep(&can_start);
 
for (i = 0; i < ATTEMPTS; i++) {
asm volatile (
"mtc1 %0,$1"
71,8 → 68,7
);
if (arg != after_arg) {
if (!sh_quiet)
printf("General reg tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
TPRINTF("General reg tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
89,13 → 85,13
thread_detach(THREAD);
waitq_sleep(&can_start);
 
for (i = 0; i < ATTEMPTS; i++) {
asm volatile (
"mtc1 %0,$1"
: "=r" (arg)
);
 
scheduler();
asm volatile (
"mfc1 %0,$1"
103,8 → 99,7
);
if (arg != after_arg) {
if (!sh_quiet)
printf("General reg tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
TPRINTF("General reg tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
113,24 → 108,21
}
 
 
char * test_mips2(bool quiet)
char *test_mips2(void)
{
unsigned int i, total = 0;
sh_quiet = quiet;
waitq_initialize(&can_start);
atomic_set(&threads_ok, 0);
atomic_set(&threads_fault, 0);
if (!quiet)
printf("Creating %u threads... ", 2 * THREADS);
 
TPRINTF("Creating %u threads... ", 2 * THREADS);
for (i = 0; i < THREADS; i++) {
thread_t *t;
if (!(t = thread_create(testit1, (void *) ((unative_t) 2 * i), TASK, 0, "testit1", false))) {
if (!quiet)
printf("could not create thread %u\n", 2 * i);
TPRINTF("could not create thread %u\n", 2 * i);
break;
}
thread_ready(t);
137,8 → 129,7
total++;
if (!(t = thread_create(testit2, (void *) ((unative_t) 2 * i + 1), TASK, 0, "testit2", false))) {
if (!quiet)
printf("could not create thread %u\n", 2 * i + 1);
TPRINTF("could not create thread %u\n", 2 * i + 1);
break;
}
thread_ready(t);
145,15 → 136,13
total++;
}
if (!quiet)
printf("ok\n");
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while (atomic_get(&threads_ok) != (long) total) {
if (!quiet)
printf("Threads left: %d\n", total - atomic_get(&threads_ok));
TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
thread_sleep(1);
}
162,5 → 151,3
return "Test failed";
}
 
#endif
/branches/arm/kernel/test/fpu/sse1.c
26,8 → 26,6
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#if (defined(ia32) || defined(amd64) || defined(ia32xen))
 
#include <print.h>
#include <debug.h>
 
38,41 → 36,38
 
#include <arch.h>
 
#define THREADS 25
#define DELAY 10000L
#define ATTEMPTS 5
#define THREADS 25
#define DELAY 10000L
#define ATTEMPTS 5
 
static atomic_t threads_ok;
static atomic_t threads_fault;
static waitq_t can_start;
static bool sh_quiet;
 
 
static void testit1(void *data)
{
int i;
int arg __attribute__((aligned(16))) = (int) ((unative_t) data);
int after_arg __attribute__((aligned(16)));
 
thread_detach(THREAD);
waitq_sleep(&can_start);
 
for (i = 0; i < ATTEMPTS; i++) {
asm volatile (
"movlpd %0, %%xmm2\n"
: "=m" (arg)
"movlpd %[arg], %%xmm2\n"
: [arg] "=m" (arg)
);
 
delay(DELAY);
asm volatile (
"movlpd %%xmm2, %0\n"
: "=m" (after_arg)
"movlpd %%xmm2, %[after_arg]\n"
: [after_arg] "=m" (after_arg)
);
if (arg != after_arg) {
if (!sh_quiet)
printf("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
TPRINTF("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
89,22 → 84,21
thread_detach(THREAD);
waitq_sleep(&can_start);
 
for (i = 0; i < ATTEMPTS; i++) {
asm volatile (
"movlpd %0, %%xmm2\n"
: "=m" (arg)
"movlpd %[arg], %%xmm2\n"
: [arg] "=m" (arg)
);
 
scheduler();
asm volatile (
"movlpd %%xmm2, %0\n"
: "=m" (after_arg)
"movlpd %%xmm2, %[after_arg]\n"
: [after_arg] "=m" (after_arg)
);
if (arg != after_arg) {
if (!sh_quiet)
printf("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
TPRINTF("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg);
atomic_inc(&threads_fault);
break;
}
112,25 → 106,21
atomic_inc(&threads_ok);
}
 
 
char * test_sse1(bool quiet)
char *test_sse1(void)
{
unsigned int i, total = 0;
sh_quiet = quiet;
waitq_initialize(&can_start);
atomic_set(&threads_ok, 0);
atomic_set(&threads_fault, 0);
if (!quiet)
printf("Creating %u threads... ", 2 * THREADS);
 
TPRINTF("Creating %u threads... ", 2 * THREADS);
for (i = 0; i < THREADS; i++) {
thread_t *t;
if (!(t = thread_create(testit1, (void *) ((unative_t) 2 * i), TASK, 0, "testit1", false))) {
if (!quiet)
printf("could not create thread %u\n", 2 * i);
TPRINTF("could not create thread %u\n", 2 * i);
break;
}
thread_ready(t);
137,8 → 127,7
total++;
if (!(t = thread_create(testit2, (void *) ((unative_t) 2 * i + 1), TASK, 0, "testit2", false))) {
if (!quiet)
printf("could not create thread %u\n", 2 * i + 1);
TPRINTF("could not create thread %u\n", 2 * i + 1);
break;
}
thread_ready(t);
145,15 → 134,13
total++;
}
if (!quiet)
printf("ok\n");
TPRINTF("ok\n");
thread_sleep(1);
waitq_wakeup(&can_start, WAKEUP_ALL);
while (atomic_get(&threads_ok) != (long) total) {
if (!quiet)
printf("Threads left: %d\n", total - atomic_get(&threads_ok));
TPRINTF("Threads left: %d\n", total - atomic_get(&threads_ok));
thread_sleep(1);
}
162,5 → 149,3
return "Test failed";
}
 
#endif
/branches/arm/kernel/test/fpu/mips2.def
1,4 → 1,3
#ifdef mips32
{
"mips2",
"MIPS FPU test",
5,4 → 4,3
&test_mips2,
true
},
#endif
/branches/arm/kernel/test/fpu/fpu1.def
1,4 → 1,3
#if (defined(ia32) || defined(amd64) || defined(ia64) || defined(ia32xen))
{
"fpu1",
"Intel FPU test",
5,4 → 4,3
&test_fpu1,
true
},
#endif
/branches/arm/kernel/test/fpu/sse1.def
1,4 → 1,3
#if (defined(ia32) || defined(amd64) || defined(ia32xen))
{
"sse1",
"Intel SEE test",
5,4 → 4,3
&test_sse1,
true
},
#endif
/branches/arm/kernel/test/sysinfo/sysinfo1.c
32,9 → 32,9
#include <test.h>
#include <sysinfo/sysinfo.h>
 
char * test_sysinfo1(bool quiet)
char *test_sysinfo1(void)
{
if (!quiet)
if (!test_quiet)
sysinfo_dump(NULL, 0);
return NULL;
}
/branches/arm/kernel/test/fault/fault1.c
36,8 → 36,7
 
#include <arch.h>
 
 
char * test_fault1(bool quiet)
char *test_fault1(void)
{
((int *)(0))[1] = 0;
/branches/arm/kernel/test/atomic/atomic1.c
31,7 → 31,7
#include <atomic.h>
#include <debug.h>
 
char * test_atomic1(bool quiet)
char *test_atomic1(void)
{
atomic_t a;
/branches/arm/kernel/test/print/print2.c
0,0 → 1,57
/*
* Copyright (c) 2005 Josef Cejka
* 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.
*/
 
#include <print.h>
#include <test.h>
 
char *test_print2(void)
{
TPRINTF("Testing printf(\"%%c %%3.2c %%-3.2c %%2.3c %%-2.3c\", 'a', 'b', 'c', 'd', 'e'):\n");
TPRINTF("Expected output: [a] [ b] [c ] [ d] [e ]\n");
TPRINTF("Real output: [%c] [%3.2c] [%-3.2c] [%2.3c] [%-2.3c]\n\n", 'a', 'b', 'c', 'd', 'e');
TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", 1, 2, 3, 4, 5):\n");
TPRINTF("Expected output: [1] [ 02] [03 ] [004] [005]\n");
TPRINTF("Real output: [%d] [%3.2d] [%-3.2d] [%2.3d] [%-2.3d]\n\n", 1, 2, 3, 4, 5);
TPRINTF("Testing printf(\"%%d %%3.2d %%-3.2d %%2.3d %%-2.3d\", -1, -2, -3, -4, -5):\n");
TPRINTF("Expected output: [-1] [-02] [-03] [-004] [-005]\n");
TPRINTF("Real output: [%d] [%3.2d] [%-3.2d] [%2.3d] [%-2.3d]\n\n", -1, -2, -3, -4, -5);
TPRINTF("Testing printf(\"%%#x %%5.3#x %%-5.3#x %%3.5#x %%-3.5#x\", 17, 18, 19, 20, 21):\n");
TPRINTF("Expected output: [0x11] [0x012] [0x013] [0x00014] [0x00015]\n");
TPRINTF("Real output: [%#x] [%#5.3x] [%#-5.3x] [%#3.5x] [%#-3.5x]\n\n", 17, 18, 19, 20, 21);
unative_t nat = 0x12345678u;
TPRINTF("Testing printf(\"%%#" PRIx64 " %%#" PRIx32 " %%#" PRIx16 " %%#" PRIx8 " %%#" PRIxn " %%#" PRIx64 " %%s\", 0x1234567887654321ll, 0x12345678, 0x1234, 0x12, nat, 0x1234567887654321ull, \"Lovely string\"):\n");
TPRINTF("Expected output: [0x1234567887654321] [0x12345678] [0x1234] [0x12] [0x12345678] [0x1234567887654321] \"Lovely string\"\n");
TPRINTF("Real output: [%#" PRIx64 "] [%#" PRIx32 "] [%#" PRIx16 "] [%#" PRIx8 "] [%#" PRIxn "] [%#" PRIx64 "] \"%s\"\n\n", 0x1234567887654321ll, 0x12345678, 0x1234, 0x12, nat, 0x1234567887654321ull, "Lovely string");
return NULL;
}
/branches/arm/kernel/test/print/print3.c
0,0 → 1,61
/*
* Copyright (c) 2005 Josef Cejka
* 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.
*/
 
#include <print.h>
#include <macros.h>
#include <test.h>
 
#define BUFFER_SIZE 32
 
char *test_print3(void)
{
char buffer[BUFFER_SIZE];
int retval;
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Short text without parameters.\"):\n");
TPRINTF("Expected result: retval=30 buffer=\"Short text without parameters.\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters.");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Very very very long text without parameters.\"):\n");
TPRINTF("Expected result: retval=44 buffer=\"Very very very long text withou\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters.");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Short %%s.\", \"text\"):\n");
TPRINTF("Expected result: retval=11 buffer=\"Short text.\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Short %s.", "text");
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
TPRINTF("Testing snprintf(buffer, " STRING(BUFFER_SIZE) ", \"Very long %%s. This text's length is more than %%d. We are interested in the result.\", \"text\", " STRING(BUFFER_SIZE) "):\n");
TPRINTF("Expected result: retval=84 buffer=\"Very long text. This text's len\"\n");
retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text's length is more than %d. We are interested in the result.", "text", BUFFER_SIZE);
TPRINTF("Real result: retval=%d buffer=\"%s\"\n\n", retval, buffer);
return NULL;
}
/branches/arm/kernel/test/print/print4.c
0,0 → 1,82
/*
* Copyright (c) 2009 Martin Decky
* 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.
*/
 
#include <print.h>
#include <test.h>
 
char *test_print4(void)
{
TPRINTF("ASCII printable characters (32 - 127) using printf(\"%%c\") and printf(\"%%lc\"):\n");
uint8_t group;
for (group = 1; group < 4; group++) {
TPRINTF("%#" PRIx8 ": ", group << 5);
uint8_t index;
for (index = 0; index < 32; index++)
TPRINTF("%c", (char) ((group << 5) + index));
TPRINTF(" ");
for (index = 0; index < 32; index++)
TPRINTF("%lc", (wchar_t) ((group << 5) + index));
TPRINTF("\n");
}
TPRINTF("\nExtended ASCII characters (128 - 255) using printf(\"%%lc\"):\n");
for (group = 4; group < 8; group++) {
TPRINTF("%#" PRIx8 ": ", group << 5);
uint8_t index;
for (index = 0; index < 32; index++)
TPRINTF("%lc", (wchar_t) ((group << 5) + index));
TPRINTF("\n");
}
TPRINTF("\nUTF-8 strings using printf(\"%%s\"):\n");
TPRINTF("English: %s\n", "Quick brown fox jumps over the lazy dog");
TPRINTF("Czech: %s\n", "Příliš žluťoučký kůň úpěl ďábelské ódy");
TPRINTF("Greek: %s\n", "Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε");
TPRINTF("Hebrew: %s\n", "משוואת ברנולי היא משוואה בהידרודינמיקה");
TPRINTF("Arabic: %s\n", "التوزيع الجغرافي للحمل العنقودي");
TPRINTF("Russian: %s\n", "Леннон познакомился с художницей-авангардисткой");
TPRINTF("Armenian: %s\n", "Սկսեց հրատարակվել Երուսաղեմի հայկական");
TPRINTF("\nUTF-32 strings using printf(\"%%ls\"):\n");
TPRINTF("English: %ls\n", L"Quick brown fox jumps over the lazy dog");
TPRINTF("Czech: %ls\n", L"Příliš žluťoučký kůň úpěl ďábelské ódy");
TPRINTF("Greek: %ls\n", L"Ὦ ξεῖν’, ἀγγέλλειν Λακεδαιμονίοις ὅτι τῇδε");
TPRINTF("Hebrew: %ls\n", L"משוואת ברנולי היא משוואה בהידרודינמיקה");
TPRINTF("Arabic: %ls\n", L"التوزيع الجغرافي للحمل العنقودي");
TPRINTF("Russian: %ls\n", L"Леннон познакомился с художницей-авангардисткой");
TPRINTF("Armenian: %ls\n", L"Սկսեց հրատարակվել Երուսաղեմի հայկական");
return NULL;
}
/branches/arm/kernel/test/print/print1.c
29,44 → 29,27
#include <print.h>
#include <test.h>
 
#define BUFFER_SIZE 32
 
char * test_print1(bool quiet)
char *test_print1(void)
{
if (!quiet) {
int retval;
unative_t nat = 0x12345678u;
char buffer[BUFFER_SIZE];
printf(" text 10.8s %*.*s \n", 5, 3, "text");
printf(" very long text 10.8s %10.8s \n", "very long text");
printf(" text 8.10s %8.10s \n", "text");
printf(" very long text 8.10s %8.10s \n", "very long text");
printf(" char: c '%c', 3.2c '%3.2c', -3.2c '%-3.2c', 2.3c '%2.3c', -2.3c '%-2.3c' \n", 'a', 'b', 'c', 'd', 'e');
printf(" int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n", 1, 1, 1, 1, 1);
printf(" -int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n", -1, -1, -1, -1, -1);
printf(" 0xint: x '%#x', 5.3x '%#5.3x', -5.3x '%#-5.3x', 3.5x '%#3.5x', -3.5x '%#-3.5x' \n", 17, 17, 17, 17, 17);
printf("'%#llx' 64bit, '%#x' 32bit, '%#hhx' 8bit, '%#hx' 16bit, unative_t '%#" PRIxn "'. '%#llx' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, nat, 0x1234567887654321ull, "Lovely string" );
printf(" Print to NULL '%s'\n", NULL);
retval = snprintf(buffer, BUFFER_SIZE, "Short text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
retval = snprintf(buffer, BUFFER_SIZE, "Very very very long text without parameters.");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print short text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Short %s", "text");
printf("Result is: '%s', retval = %d\n", buffer, retval);
printf("Print long text to %d char long buffer via snprintf.\n", BUFFER_SIZE);
retval = snprintf(buffer, BUFFER_SIZE, "Very long %s. This text`s length is more than %d. We are interested in the result.", "text" , BUFFER_SIZE);
printf("Result is: '%s', retval = %d\n", buffer, retval);
}
TPRINTF("Testing printf(\"%%*.*s\", 5, 3, \"text\"):\n");
TPRINTF("Expected output: \" tex\"\n");
TPRINTF("Real output: \"%*.*s\"\n\n", 5, 3, "text");
TPRINTF("Testing printf(\"%%10.8s\", \"very long text\"):\n");
TPRINTF("Expected output: \" very lon\"\n");
TPRINTF("Real output: \"%10.8s\"\n\n", "very long text");
TPRINTF("Testing printf(\"%%8.10s\", \"text\"):\n");
TPRINTF("Expected output: \"text\"\n");
TPRINTF("Real output: \"%8.10s\"\n\n", "text");
TPRINTF("Testing printf(\"%%8.10s\", \"very long text\"):\n");
TPRINTF("Expected output: \"very long \"\n");
TPRINTF("Real output: \"%8.10s\"\n\n", "very long text");
TPRINTF("Testing printf(\"%%s\", NULL):\n");
TPRINTF("Expected output: \"(NULL)\"\n");
TPRINTF("Real output: \"%s\"\n\n", NULL);
return NULL;
}
/branches/arm/kernel/test/print/print1.def
1,6 → 1,6
{
"print1",
"Printf test",
"String printf test",
&test_print1,
true
},
/branches/arm/kernel/test/print/print2.def
0,0 → 1,6
{
"print2",
"Numeric printf test",
&test_print2,
true
},
/branches/arm/kernel/test/print/print3.def
0,0 → 1,6
{
"print3",
"Buffered printf test",
&test_print3,
true
},
/branches/arm/kernel/test/print/print4.def
0,0 → 1,6
{
"print4",
"Unicode test",
&test_print4,
true
},