/branches/network/kernel/kernel.config |
---|
File deleted |
/branches/network/kernel/test/avltree/avltree1.def |
---|
1,6 → 1,6 |
{ |
"avltree1", |
"Test Avl tree operations", |
"Test AVL tree operations", |
&test_avltree1, |
true |
}, |
/branches/network/kernel/test/synch/rwlock4.c |
---|
60,7 → 60,7 |
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; |
} |
/branches/network/kernel/test/synch/semaphore2.c |
---|
53,7 → 53,7 |
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; |
} |
/branches/network/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(bool quiet) |
{ |
return NULL; |
} |
/branches/network/kernel/test/debug/mips1.def |
---|
1,4 → 1,3 |
#ifdef mips32 |
{ |
"mips1", |
"MIPS debug test", |
5,4 → 4,3 |
&test_mips1, |
false |
}, |
#endif |
/branches/network/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,10 |
#include <arch.h> |
char * test_mips1(bool quiet) |
char *test_mips1(bool quiet) |
{ |
if (!quiet) |
printf("You should enter kconsole debug mode now.\n"); |
printf("If kconsole is compiled in, you should enter debug mode now.\n"); |
asm volatile ( |
"break\n" |
49,5 → 47,3 |
return "Back from debug mode"; |
} |
#endif |
/branches/network/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/network/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> |
47,10 → 45,10 |
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/network/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(bool quiet) |
{ |
return NULL; |
} |
/branches/network/kernel/test/fpu/fpu1.c |
---|
File deleted |
/branches/network/kernel/test/fpu/fpu1_ia64.c |
---|
0,0 → 1,179 |
/* |
* 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 bool sh_quiet; |
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) { |
if (!sh_quiet) |
printf("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) { |
if (!sh_quiet) |
printf("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(bool quiet) |
{ |
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); |
for (i = 0; i < THREADS; i++) { |
thread_t *t; |
if (!(t = thread_create(e, NULL, TASK, 0, "e", false))) { |
if (!quiet) |
printf("could not create thread %u\n", 2 * i); |
break; |
} |
thread_ready(t); |
total++; |
if (!(t = thread_create(pi, NULL, TASK, 0, "pi", false))) { |
if (!quiet) |
printf("could not create thread %u\n", 2 * i + 1); |
break; |
} |
thread_ready(t); |
total++; |
} |
if (!quiet) |
printf("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)); |
thread_sleep(1); |
} |
if (atomic_get(&threads_fault) == 0) |
return NULL; |
return "Test failed"; |
} |
/branches/network/kernel/test/fpu/fpu1_x86.c |
---|
0,0 → 1,176 |
/* |
* 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 bool sh_quiet; |
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) { |
if (!sh_quiet) |
printf("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) { |
if (!sh_quiet) |
printf("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(bool quiet) |
{ |
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); |
for (i = 0; i < THREADS; i++) { |
thread_t *t; |
if (!(t = thread_create(e, NULL, TASK, 0, "e", false))) { |
if (!quiet) |
printf("could not create thread %u\n", 2 * i); |
break; |
} |
thread_ready(t); |
total++; |
if (!(t = thread_create(pi, NULL, TASK, 0, "pi", false))) { |
if (!quiet) |
printf("could not create thread %u\n", 2 * i + 1); |
break; |
} |
thread_ready(t); |
total++; |
} |
if (!quiet) |
printf("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)); |
thread_sleep(1); |
} |
if (atomic_get(&threads_fault) == 0) |
return NULL; |
return "Test failed"; |
} |
/branches/network/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(bool quiet) |
{ |
return NULL; |
} |
/branches/network/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(bool quiet) |
{ |
return NULL; |
} |
/branches/network/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(bool quiet) |
{ |
return NULL; |
} |
/branches/network/kernel/test/fpu/mips2.def |
---|
1,4 → 1,3 |
#ifdef mips32 |
{ |
"mips2", |
"MIPS FPU test", |
5,4 → 4,3 |
&test_mips2, |
true |
}, |
#endif |
/branches/network/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/network/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/network/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,9 → 36,9 |
#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; |
56,7 → 54,7 |
thread_detach(THREAD); |
waitq_sleep(&can_start); |
for (i = 0; i < ATTEMPTS; i++) { |
asm volatile ( |
"mtc1 %0,$1" |
89,13 → 87,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" |
124,7 → 122,7 |
if (!quiet) |
printf("Creating %u threads... ", 2 * THREADS); |
for (i = 0; i < THREADS; i++) { |
thread_t *t; |
162,5 → 160,3 |
return "Test failed"; |
} |
#endif |
/branches/network/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,9 → 36,9 |
#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; |
60,14 → 58,14 |
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) { |
92,14 → 90,14 |
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) { |
162,5 → 160,3 |
return "Test failed"; |
} |
#endif |
/branches/network/kernel/genarch/include/kbd/i8042.h |
---|
File deleted |
/branches/network/kernel/genarch/include/kbd/scanc.h |
---|
File deleted |
/branches/network/kernel/genarch/include/kbd/key.h |
---|
File deleted |
/branches/network/kernel/genarch/include/kbd/scanc_pc.h |
---|
File deleted |
/branches/network/kernel/genarch/include/kbd/z8530.h |
---|
File deleted |
/branches/network/kernel/genarch/include/kbd/scanc_sun.h |
---|
File deleted |
/branches/network/kernel/genarch/include/kbd/ns16550.h |
---|
File deleted |
/branches/network/kernel/genarch/include/kbrd/kbrd.h |
---|
0,0 → 1,46 |
/* |
* 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> |
extern void kbrd_init(indev_t *devin); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/network/kernel/genarch/include/kbrd/scanc_pc.h |
---|
0,0 → 1,57 |
/* |
* 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_ESC 0x01 |
#define SC_BACKSPACE 0x0e |
#define SC_LSHIFT 0x2a |
#define SC_RSHIFT 0x36 |
#define SC_CAPSLOCK 0x3a |
#define SC_SPEC_ESCAPE 0xe0 |
#define SC_LEFTARR 0x4b |
#define SC_RIGHTARR 0x4d |
#define SC_UPARR 0x48 |
#define SC_DOWNARR 0x50 |
#define SC_DELETE 0x53 |
#define SC_HOME 0x47 |
#define SC_END 0x4f |
#endif |
/** @} |
*/ |
/branches/network/kernel/genarch/include/kbrd/scanc_sun.h |
---|
0,0 → 1,57 |
/* |
* 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_ESC 0x1d |
#define SC_BACKSPACE 0x2b |
#define SC_LSHIFT 0x63 |
#define SC_RSHIFT 0x6e |
#define SC_CAPSLOCK 0x77 |
#define SC_SPEC_ESCAPE 0xe0 /* ??? */ |
#define SC_LEFTARR 0x18 |
#define SC_RIGHTARR 0x1c |
#define SC_UPARR 0x14 |
#define SC_DOWNARR 0x1b |
#define SC_DELETE 0x42 |
#define SC_HOME 0x34 |
#define SC_END 0x4a |
#endif |
/** @} |
*/ |
/branches/network/kernel/genarch/include/kbrd/scanc.h |
---|
0,0 → 1,47 |
/* |
* 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_ |
#define SPECIAL '?' |
extern char sc_primary_map[]; |
extern char sc_secondary_map[]; |
#endif |
/** @} |
*/ |
/branches/network/kernel/genarch/include/kbrd |
---|
Property changes: |
Added: svn:mergeinfo |
/branches/network/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,14 |
#ifndef KERN_FONT_8X16_H_ |
#define KERN_FONT_8X16_H_ |
#define FONT_GLIPHS 256 |
#define FONT_SCANLINES 16 |
#define FONT_GLYPHS 256 |
#define FONT_WIDTH 8 |
#define FONT_SCANLINES 16 |
extern unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES]; |
#include <arch/types.h> |
extern uint8_t fb_font[FONT_GLYPHS * FONT_SCANLINES]; |
#endif |
/** @} |
/branches/network/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/network/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,15 → 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_0_8_8_8 6 |
#define VISUAL_BGR_8_8_8 7 |
#endif |
/branches/network/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/network/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/network/kernel/genarch/include/drivers/ns16550/ns16550.h |
---|
0,0 → 1,75 |
/* |
* 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 { |
ns16550_t *ns16550; |
irq_t irq; |
indev_t kbrdin; |
} ns16550_instance_t; |
extern indev_t *ns16550_init(ns16550_t *, inr_t, cir_t, void *); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/network/kernel/genarch/include/drivers/dsrln/dsrlnin.h |
---|
0,0 → 1,60 |
/* |
* 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 kbrdin; |
} dsrlnin_instance_t; |
extern indev_t *dsrlnin_init(dsrlnin_t *, inr_t); |
#endif |
/** @} |
*/ |
/branches/network/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/network/kernel/genarch/include/drivers/i8042/i8042.h |
---|
0,0 → 1,60 |
/* |
* 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 indev_t *i8042_init(i8042_t *, inr_t); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/network/kernel/genarch/include/drivers/z8530/z8530.h |
---|
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 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 indev_t *z8530_init(z8530_t *, inr_t, cir_t, void *); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/network/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/network/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/network/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/network/kernel/genarch/include/srln/srln.h |
---|
0,0 → 1,46 |
/* |
* 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> |
extern void srln_init(indev_t *devin); |
#endif |
/** @} |
*/ |
/branches/network/kernel/genarch/Makefile.inc |
---|
33,68 → 33,85 |
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_DSRLNIN),y) |
GENARCH_SOURCES += \ |
genarch/src/drivers/dsrln/dsrlnin.c |
endif |
ifeq ($(CONFIG_DSRLNOUT),y) |
GENARCH_SOURCES += \ |
genarch/src/drivers/dsrln/dsrlnout.c |
endif |
ifeq ($(CONFIG_I8042),y) |
GENARCH_SOURCES += \ |
genarch/src/kbd/i8042.c \ |
genarch/src/kbd/key.c \ |
genarch/src/kbd/scanc_pc.c |
genarch/src/drivers/i8042/i8042.c |
endif |
## Sun keyboard |
ifeq ($(CONFIG_SUN_KBD),y) |
ifeq ($(CONFIG_NS16550),y) |
GENARCH_SOURCES += \ |
genarch/src/kbd/key.c \ |
genarch/src/kbd/scanc_sun.c |
genarch/src/drivers/ns16550/ns16550.c |
endif |
## z8530 controller |
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_PC_KBD),y) |
GENARCH_SOURCES += \ |
genarch/src/kbd/ns16550.c |
genarch/src/kbrd/kbrd.c \ |
genarch/src/kbrd/scanc_pc.c |
endif |
ifeq ($(CONFIG_SUN_KBD),y) |
GENARCH_SOURCES += \ |
genarch/src/kbrd/kbrd.c \ |
genarch/src/kbrd/scanc_sun.c |
endif |
## OpenFirmware Device Tree |
ifeq ($(CONFIG_OFW_TREE), y) |
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 \ |
102,3 → 119,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/network/kernel/genarch/src/kbd/i8042.c |
---|
File deleted |
/branches/network/kernel/genarch/src/kbd/key.c |
---|
File deleted |
/branches/network/kernel/genarch/src/kbd/z8530.c |
---|
File deleted |
/branches/network/kernel/genarch/src/kbd/scanc_pc.c |
---|
File deleted |
/branches/network/kernel/genarch/src/kbd/scanc_sun.c |
---|
File deleted |
/branches/network/kernel/genarch/src/kbd/ns16550.c |
---|
File deleted |
/branches/network/kernel/genarch/src/kbrd/kbrd.c |
---|
0,0 → 1,208 |
/* |
* 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 |
#include <synch/spinlock.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <proc/thread.h> |
#include <arch.h> |
#include <macros.h> |
#ifdef CONFIG_SUN_KBD |
#define IGNORE_CODE 0x7f |
#endif |
#define KEY_RELEASE 0x80 |
#define PRESSED_SHIFT (1 << 0) |
#define PRESSED_CAPSLOCK (1 << 1) |
#define LOCKED_CAPSLOCK (1 << 0) |
static indev_t kbrdout; |
indev_operations_t kbrdout_ops = { |
.poll = NULL |
}; |
SPINLOCK_INITIALIZE(keylock); /**< keylock protects keyflags and lockflags. */ |
static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
static void key_released(uint8_t); |
static void key_pressed(uint8_t); |
static void kkbrd(void *arg) |
{ |
indev_t *in = (indev_t *) arg; |
while (true) { |
uint8_t sc = _getc(in); |
#ifdef CONFIG_SUN_KBD |
if (sc == IGNORE_CODE) |
continue; |
#endif |
if (sc & KEY_RELEASE) |
key_released(sc ^ KEY_RELEASE); |
else |
key_pressed(sc); |
} |
} |
void kbrd_init(indev_t *devin) |
{ |
indev_initialize("kbrd", &kbrdout, &kbrdout_ops); |
thread_t *thread |
= thread_create(kkbrd, devin, TASK, 0, "kkbrd", false); |
if (thread) { |
stdin = &kbrdout; |
thread_ready(thread); |
} |
} |
/** Process release of key. |
* |
* @param sc Scancode of the key being released. |
*/ |
void key_released(uint8_t sc) |
{ |
spinlock_lock(&keylock); |
switch (sc) { |
case SC_LSHIFT: |
case SC_RSHIFT: |
keyflags &= ~PRESSED_SHIFT; |
break; |
case SC_CAPSLOCK: |
keyflags &= ~PRESSED_CAPSLOCK; |
if (lockflags & LOCKED_CAPSLOCK) |
lockflags &= ~LOCKED_CAPSLOCK; |
else |
lockflags |= LOCKED_CAPSLOCK; |
break; |
default: |
break; |
} |
spinlock_unlock(&keylock); |
} |
/** Process keypress. |
* |
* @param sc Scancode of the key being pressed. |
*/ |
void key_pressed(uint8_t sc) |
{ |
char *map = sc_primary_map; |
char ascii = sc_primary_map[sc]; |
bool shift, capslock; |
bool letter = false; |
spinlock_lock(&keylock); |
switch (sc) { |
case SC_LSHIFT: |
case SC_RSHIFT: |
keyflags |= PRESSED_SHIFT; |
break; |
case SC_CAPSLOCK: |
keyflags |= PRESSED_CAPSLOCK; |
break; |
case SC_SPEC_ESCAPE: |
break; |
case SC_LEFTARR: |
indev_push_character(stdin, 0x1b); |
indev_push_character(stdin, 0x5b); |
indev_push_character(stdin, 0x44); |
break; |
case SC_RIGHTARR: |
indev_push_character(stdin, 0x1b); |
indev_push_character(stdin, 0x5b); |
indev_push_character(stdin, 0x43); |
break; |
case SC_UPARR: |
indev_push_character(stdin, 0x1b); |
indev_push_character(stdin, 0x5b); |
indev_push_character(stdin, 0x41); |
break; |
case SC_DOWNARR: |
indev_push_character(stdin, 0x1b); |
indev_push_character(stdin, 0x5b); |
indev_push_character(stdin, 0x42); |
break; |
case SC_HOME: |
indev_push_character(stdin, 0x1b); |
indev_push_character(stdin, 0x4f); |
indev_push_character(stdin, 0x48); |
break; |
case SC_END: |
indev_push_character(stdin, 0x1b); |
indev_push_character(stdin, 0x4f); |
indev_push_character(stdin, 0x46); |
break; |
case SC_DELETE: |
indev_push_character(stdin, 0x1b); |
indev_push_character(stdin, 0x5b); |
indev_push_character(stdin, 0x33); |
indev_push_character(stdin, 0x7e); |
break; |
default: |
letter = islower(ascii); |
capslock = (keyflags & PRESSED_CAPSLOCK) || |
(lockflags & LOCKED_CAPSLOCK); |
shift = keyflags & PRESSED_SHIFT; |
if (letter && capslock) |
shift = !shift; |
if (shift) |
map = sc_secondary_map; |
indev_push_character(stdin, map[sc]); |
break; |
} |
spinlock_unlock(&keylock); |
} |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/network/kernel/genarch/src/kbrd/scanc_pc.c |
---|
0,0 → 1,200 |
/* |
* 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> |
/** Primary meaning of scancodes. */ |
char sc_primary_map[] = { |
SPECIAL, /* 0x00 */ |
SPECIAL, /* 0x01 - Esc */ |
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', |
'\b', /* 0x0e - Backspace */ |
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', |
SPECIAL, /* 0x1d - LCtrl */ |
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', |
'`', |
SPECIAL, /* 0x2a - LShift */ |
'\\', |
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', |
SPECIAL, /* 0x36 - RShift */ |
'*', |
SPECIAL, /* 0x38 - LAlt */ |
' ', |
SPECIAL, /* 0x3a - CapsLock */ |
SPECIAL, /* 0x3b - F1 */ |
SPECIAL, /* 0x3c - F2 */ |
SPECIAL, /* 0x3d - F3 */ |
SPECIAL, /* 0x3e - F4 */ |
SPECIAL, /* 0x3f - F5 */ |
SPECIAL, /* 0x40 - F6 */ |
SPECIAL, /* 0x41 - F7 */ |
SPECIAL, /* 0x42 - F8 */ |
SPECIAL, /* 0x43 - F9 */ |
SPECIAL, /* 0x44 - F10 */ |
SPECIAL, /* 0x45 - NumLock */ |
SPECIAL, /* 0x46 - ScrollLock */ |
'7', '8', '9', '-', |
'4', '5', '6', '+', |
'1', '2', '3', |
'0', '.', |
SPECIAL, /* 0x54 - Alt-SysRq */ |
SPECIAL, /* 0x55 - F11/F12/PF1/FN */ |
SPECIAL, /* 0x56 - unlabelled key next to LAlt */ |
SPECIAL, /* 0x57 - F11 */ |
SPECIAL, /* 0x58 - F12 */ |
SPECIAL, /* 0x59 */ |
SPECIAL, /* 0x5a */ |
SPECIAL, /* 0x5b */ |
SPECIAL, /* 0x5c */ |
SPECIAL, /* 0x5d */ |
SPECIAL, /* 0x5e */ |
SPECIAL, /* 0x5f */ |
SPECIAL, /* 0x60 */ |
SPECIAL, /* 0x61 */ |
SPECIAL, /* 0x62 */ |
SPECIAL, /* 0x63 */ |
SPECIAL, /* 0x64 */ |
SPECIAL, /* 0x65 */ |
SPECIAL, /* 0x66 */ |
SPECIAL, /* 0x67 */ |
SPECIAL, /* 0x68 */ |
SPECIAL, /* 0x69 */ |
SPECIAL, /* 0x6a */ |
SPECIAL, /* 0x6b */ |
SPECIAL, /* 0x6c */ |
SPECIAL, /* 0x6d */ |
SPECIAL, /* 0x6e */ |
SPECIAL, /* 0x6f */ |
SPECIAL, /* 0x70 */ |
SPECIAL, /* 0x71 */ |
SPECIAL, /* 0x72 */ |
SPECIAL, /* 0x73 */ |
SPECIAL, /* 0x74 */ |
SPECIAL, /* 0x75 */ |
SPECIAL, /* 0x76 */ |
SPECIAL, /* 0x77 */ |
SPECIAL, /* 0x78 */ |
SPECIAL, /* 0x79 */ |
SPECIAL, /* 0x7a */ |
SPECIAL, /* 0x7b */ |
SPECIAL, /* 0x7c */ |
SPECIAL, /* 0x7d */ |
SPECIAL, /* 0x7e */ |
SPECIAL, /* 0x7f */ |
}; |
/** Secondary meaning of scancodes. */ |
char sc_secondary_map[] = { |
SPECIAL, /* 0x00 */ |
SPECIAL, /* 0x01 - Esc */ |
'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', |
SPECIAL, /* 0x0e - Backspace */ |
'\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', |
SPECIAL, /* 0x1d - LCtrl */ |
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', |
'~', |
SPECIAL, /* 0x2a - LShift */ |
'|', |
'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', |
SPECIAL, /* 0x36 - RShift */ |
'*', |
SPECIAL, /* 0x38 - LAlt */ |
' ', |
SPECIAL, /* 0x3a - CapsLock */ |
SPECIAL, /* 0x3b - F1 */ |
SPECIAL, /* 0x3c - F2 */ |
SPECIAL, /* 0x3d - F3 */ |
SPECIAL, /* 0x3e - F4 */ |
SPECIAL, /* 0x3f - F5 */ |
SPECIAL, /* 0x40 - F6 */ |
SPECIAL, /* 0x41 - F7 */ |
SPECIAL, /* 0x42 - F8 */ |
SPECIAL, /* 0x43 - F9 */ |
SPECIAL, /* 0x44 - F10 */ |
SPECIAL, /* 0x45 - NumLock */ |
SPECIAL, /* 0x46 - ScrollLock */ |
'7', '8', '9', '-', |
'4', '5', '6', '+', |
'1', '2', '3', |
'0', '.', |
SPECIAL, /* 0x54 - Alt-SysRq */ |
SPECIAL, /* 0x55 - F11/F12/PF1/FN */ |
SPECIAL, /* 0x56 - unlabelled key next to LAlt */ |
SPECIAL, /* 0x57 - F11 */ |
SPECIAL, /* 0x58 - F12 */ |
SPECIAL, /* 0x59 */ |
SPECIAL, /* 0x5a */ |
SPECIAL, /* 0x5b */ |
SPECIAL, /* 0x5c */ |
SPECIAL, /* 0x5d */ |
SPECIAL, /* 0x5e */ |
SPECIAL, /* 0x5f */ |
SPECIAL, /* 0x60 */ |
SPECIAL, /* 0x61 */ |
SPECIAL, /* 0x62 */ |
SPECIAL, /* 0x63 */ |
SPECIAL, /* 0x64 */ |
SPECIAL, /* 0x65 */ |
SPECIAL, /* 0x66 */ |
SPECIAL, /* 0x67 */ |
SPECIAL, /* 0x68 */ |
SPECIAL, /* 0x69 */ |
SPECIAL, /* 0x6a */ |
SPECIAL, /* 0x6b */ |
SPECIAL, /* 0x6c */ |
SPECIAL, /* 0x6d */ |
SPECIAL, /* 0x6e */ |
SPECIAL, /* 0x6f */ |
SPECIAL, /* 0x70 */ |
SPECIAL, /* 0x71 */ |
SPECIAL, /* 0x72 */ |
SPECIAL, /* 0x73 */ |
SPECIAL, /* 0x74 */ |
SPECIAL, /* 0x75 */ |
SPECIAL, /* 0x76 */ |
SPECIAL, /* 0x77 */ |
SPECIAL, /* 0x78 */ |
SPECIAL, /* 0x79 */ |
SPECIAL, /* 0x7a */ |
SPECIAL, /* 0x7b */ |
SPECIAL, /* 0x7c */ |
SPECIAL, /* 0x7d */ |
SPECIAL, /* 0x7e */ |
SPECIAL, /* 0x7f */ |
}; |
/** @} |
*/ |
/branches/network/kernel/genarch/src/kbrd/scanc_sun.c |
---|
0,0 → 1,304 |
/* |
* 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> |
/** Primary meaning of scancodes. */ |
char sc_primary_map[] = { |
[0x00] = SPECIAL, |
[0x01] = SPECIAL, |
[0x02] = SPECIAL, |
[0x03] = SPECIAL, |
[0x04] = SPECIAL, |
[0x05] = SPECIAL, /* F1 */ |
[0x06] = SPECIAL, /* F2 */ |
[0x07] = SPECIAL, /* F10 */ |
[0x08] = SPECIAL, /* F3 */ |
[0x09] = SPECIAL, /* F11 */ |
[0x0a] = SPECIAL, /* F4 */ |
[0x0b] = SPECIAL, /* F12 */ |
[0x0c] = SPECIAL, /* F5 */ |
[0x0d] = SPECIAL, /* RAlt */ |
[0x0e] = SPECIAL, /* F6 */ |
[0x0f] = SPECIAL, |
[0x10] = SPECIAL, /* F7 */ |
[0x11] = SPECIAL, /* F8 */ |
[0x12] = SPECIAL, /* F9 */ |
[0x13] = SPECIAL, /* LAlt */ |
[0x14] = SPECIAL, /* Up Arrow */ |
[0x15] = SPECIAL, /* Pause */ |
[0x16] = SPECIAL, |
[0x17] = SPECIAL, /* Scroll Lock */ |
[0x18] = SPECIAL, /* Left Arrow */ |
[0x19] = SPECIAL, |
[0x1a] = SPECIAL, |
[0x1b] = SPECIAL, /* Down Arrow */ |
[0x1c] = SPECIAL, /* Right Arrow */ |
[0x1d] = SPECIAL, /* 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] = SPECIAL, /* Insert */ |
[0x2d] = SPECIAL, |
[0x2e] = '/', /* numeric keypad */ |
[0x2f] = '*', /* numeric keypad */ |
[0x30] = SPECIAL, |
[0x31] = SPECIAL, |
[0x32] = '.', /* numeric keypad */ |
[0x33] = SPECIAL, |
[0x34] = SPECIAL, /* 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] = SPECIAL, /* Del */ |
[0x43] = SPECIAL, |
[0x44] = '7', /* numeric keypad */ |
[0x45] = '8', /* numeric keypad */ |
[0x46] = '9', /* numeric keypad */ |
[0x47] = '-', /* numeric keypad */ |
[0x48] = SPECIAL, |
[0x49] = SPECIAL, |
[0x4a] = SPECIAL, /* End */ |
[0x4b] = SPECIAL, |
[0x4c] = 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', /* Enter on numeric keypad */ |
[0x5b] = '4', /* numeric keypad */ |
[0x5c] = '5', /* numeric keypad */ |
[0x5d] = '6', /* numeric keypad */ |
[0x5e] = '0', /* numeric keypad */ |
[0x5f] = SPECIAL, |
[0x60] = SPECIAL, /* Page Up */ |
[0x61] = SPECIAL, |
[0x62] = SPECIAL, /* Num Lock */ |
[0x63] = SPECIAL, /* LShift */ |
[0x64] = 'z', |
[0x65] = 'x', |
[0x66] = 'c', |
[0x67] = 'v', |
[0x68] = 'b', |
[0x69] = 'n', |
[0x6a] = 'm', |
[0x6b] = ',', |
[0x6c] = '.', |
[0x6d] = '/', |
[0x6e] = SPECIAL, /* RShift */ |
[0x6f] = SPECIAL, |
[0x70] = '1', /* numeric keypad */ |
[0x71] = '2', /* numeric keypad */ |
[0x72] = '3', /* numeric keypad */ |
[0x73] = SPECIAL, |
[0x74] = SPECIAL, |
[0x75] = SPECIAL, |
[0x76] = SPECIAL, |
[0x77] = SPECIAL, /* Caps Lock */ |
[0x78] = SPECIAL, |
[0x79] = ' ', |
[0x7a] = SPECIAL, |
[0x7b] = SPECIAL, /* Page Down */ |
[0x7c] = SPECIAL, |
[0x7d] = '+', /* numeric key pad */ |
[0x7e] = SPECIAL, |
[0x7f] = SPECIAL |
}; |
/** Secondary meaning of scancodes. */ |
char sc_secondary_map[] = { |
[0x00] = SPECIAL, |
[0x01] = SPECIAL, |
[0x02] = SPECIAL, |
[0x03] = SPECIAL, |
[0x04] = SPECIAL, |
[0x05] = SPECIAL, /* F1 */ |
[0x06] = SPECIAL, /* F2 */ |
[0x07] = SPECIAL, /* F10 */ |
[0x08] = SPECIAL, /* F3 */ |
[0x09] = SPECIAL, /* F11 */ |
[0x0a] = SPECIAL, /* F4 */ |
[0x0b] = SPECIAL, /* F12 */ |
[0x0c] = SPECIAL, /* F5 */ |
[0x0d] = SPECIAL, /* RAlt */ |
[0x0e] = SPECIAL, /* F6 */ |
[0x0f] = SPECIAL, |
[0x10] = SPECIAL, /* F7 */ |
[0x11] = SPECIAL, /* F8 */ |
[0x12] = SPECIAL, /* F9 */ |
[0x13] = SPECIAL, /* LAlt */ |
[0x14] = SPECIAL, /* Up Arrow */ |
[0x15] = SPECIAL, /* Pause */ |
[0x16] = SPECIAL, |
[0x17] = SPECIAL, /* Scroll Lock */ |
[0x18] = SPECIAL, /* Left Arrow */ |
[0x19] = SPECIAL, |
[0x1a] = SPECIAL, |
[0x1b] = SPECIAL, /* Down Arrow */ |
[0x1c] = SPECIAL, /* Right Arrow */ |
[0x1d] = SPECIAL, /* Esc */ |
[0x1e] = '!', |
[0x1f] = '@', |
[0x20] = '#', |
[0x21] = '$', |
[0x22] = '%', |
[0x23] = '^', |
[0x24] = '&', |
[0x25] = '*', |
[0x26] = '(', |
[0x27] = ')', |
[0x28] = '_', |
[0x29] = '+', |
[0x2a] = '~', |
[0x2b] = SPECIAL, /* Backspace */ |
[0x2c] = SPECIAL, /* Insert */ |
[0x2d] = SPECIAL, |
[0x2e] = '/', /* numeric keypad */ |
[0x2f] = '*', /* numeric keypad */ |
[0x30] = SPECIAL, |
[0x31] = SPECIAL, |
[0x32] = '.', /* numeric keypad */ |
[0x33] = SPECIAL, |
[0x34] = SPECIAL, /* Home */ |
[0x35] = SPECIAL, /* Tab */ |
[0x36] = 'Q', |
[0x37] = 'W', |
[0x38] = 'E', |
[0x39] = 'R', |
[0x3a] = 'T', |
[0x3b] = 'Y', |
[0x3c] = 'U', |
[0x3d] = 'I', |
[0x3e] = 'O', |
[0x3f] = 'P', |
[0x40] = '{', |
[0x41] = '}', |
[0x42] = SPECIAL, /* Del */ |
[0x43] = SPECIAL, |
[0x44] = '7', /* numeric keypad */ |
[0x45] = '8', /* numeric keypad */ |
[0x46] = '9', /* numeric keypad */ |
[0x47] = '-', /* numeric keypad */ |
[0x48] = SPECIAL, |
[0x49] = SPECIAL, |
[0x4a] = SPECIAL, /* End */ |
[0x4b] = SPECIAL, |
[0x4c] = SPECIAL, /* Control */ |
[0x4d] = 'A', |
[0x4e] = 'S', |
[0x4f] = 'D', |
[0x50] = 'F', |
[0x51] = 'G', |
[0x52] = 'H', |
[0x53] = 'J', |
[0x54] = 'K', |
[0x55] = 'L', |
[0x56] = ':', |
[0x57] = '"', |
[0x58] = '|', |
[0x59] = SPECIAL, /* Enter */ |
[0x5a] = SPECIAL, /* Enter on numeric keypad */ |
[0x5b] = '4', /* numeric keypad */ |
[0x5c] = '5', /* numeric keypad */ |
[0x5d] = '6', /* numeric keypad */ |
[0x5e] = '0', /* numeric keypad */ |
[0x5f] = SPECIAL, |
[0x60] = SPECIAL, /* Page Up */ |
[0x61] = SPECIAL, |
[0x62] = SPECIAL, /* Num Lock */ |
[0x63] = SPECIAL, /* LShift */ |
[0x64] = 'Z', |
[0x65] = 'X', |
[0x66] = 'C', |
[0x67] = 'V', |
[0x68] = 'B', |
[0x69] = 'N', |
[0x6a] = 'M', |
[0x6b] = '<', |
[0x6c] = '>', |
[0x6d] = '?', |
[0x6e] = SPECIAL, /* RShift */ |
[0x6f] = SPECIAL, |
[0x70] = '1', /* numeric keypad */ |
[0x71] = '2', /* numeric keypad */ |
[0x72] = '3', /* numeric keypad */ |
[0x73] = SPECIAL, |
[0x74] = SPECIAL, |
[0x75] = SPECIAL, |
[0x76] = SPECIAL, |
[0x77] = SPECIAL, /* Caps Lock */ |
[0x78] = SPECIAL, |
[0x79] = ' ', |
[0x7a] = SPECIAL, |
[0x7b] = SPECIAL, /* Page Down */ |
[0x7c] = SPECIAL, |
[0x7d] = '+', /* numeric key pad */ |
[0x7e] = SPECIAL, |
[0x7f] = SPECIAL |
}; |
/** @} |
*/ |
/branches/network/kernel/genarch/src/kbrd |
---|
Property changes: |
Added: svn:mergeinfo |
/branches/network/kernel/genarch/src/fb/helenos.xbm |
---|
File deleted |
/branches/network/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/network/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,6 → 41,7 |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <mm/slab.h> |
#include <align.h> |
#include <panic.h> |
#include <memstr.h> |
#include <config.h> |
47,137 → 50,116 |
#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 uint8_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 BGCOLOR 0x000080 |
#define FGCOLOR 0xffff00 |
#define LOGOCOLOR 0x2020b0 |
#define CURSOR 219 |
#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 POINTPOS(x, y) ((y) * scanline + (x) * pixelbytes) |
#define COL2X(col) ((col) * FONT_WIDTH) |
#define ROW2Y(row) ((row) * FONT_SCANLINES) |
/***************************************************************/ |
/* Pixel specific fuctions */ |
#define X2COL(x) ((x) / FONT_WIDTH) |
#define Y2ROW(y) ((y) / FONT_SCANLINES) |
static void (*rgb2scr)(void *, int); |
static int (*scr2rgb)(void *); |
#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 inline int COLOR(int color) |
{ |
return invert_colors ? ~color : color; |
} |
/* Conversion routines between different color representations */ |
static void rgb_byte0888(void *dst, int rgb) |
{ |
*((int *) dst) = rgb; |
} |
static void (*rgb_conv)(void *, uint32_t); |
static int byte0888_rgb(void *src) |
{ |
return (*((int *) src)) & 0xffffff; |
} |
static void bgr_byte0888(void *dst, int rgb) |
/** ARGB 8:8:8:8 conversion |
* |
*/ |
static void rgb_0888(void *dst, uint32_t rgb) |
{ |
*((uint32_t *) dst) = BLUE(rgb, 8) << 16 | GREEN(rgb, 8) << 8 | |
RED(rgb, 8); |
*((uint32_t *) dst) = rgb & 0xffffff; |
} |
static int byte0888_bgr(void *src) |
{ |
int color = *(uint32_t *)(src); |
return ((color & 0xff) << 16) | (((color >> 8) & 0xff) << 8) | |
((color >> 16) & 0xff); |
} |
static void rgb_byte888(void *dst, int rgb) |
/** ABGR 8:8:8:8 conversion |
* |
*/ |
static void bgr_0888(void *dst, uint32_t 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 |
*((uint32_t *) dst) |
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8); |
} |
static int byte888_rgb(void *src) |
{ |
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 |
} |
/** 16-bit depth (5:5:5) */ |
static void rgb_byte555(void *dst, int rgb) |
/** RGB 8:8:8 conversion |
* |
*/ |
static void rgb_888(void *dst, uint32_t rgb) |
{ |
/* 5-bit, 5-bits, 5-bits */ |
*((uint16_t *) dst) = RED(rgb, 5) << 10 | GREEN(rgb, 5) << 5 | |
BLUE(rgb, 5); |
((uint8_t *) dst)[0] = BLUE(rgb, 8); |
((uint8_t *) dst)[1] = GREEN(rgb, 8); |
((uint8_t *) dst)[2] = RED(rgb, 8); |
} |
/** 16-bit depth (5:5:5) */ |
static int byte555_rgb(void *src) |
/** BGR 8:8:8 conversion |
* |
*/ |
static void bgr_888(void *dst, uint32_t rgb) |
{ |
int color = *(uint16_t *)(src); |
return (((color >> 10) & 0x1f) << (16 + 3)) | |
(((color >> 5) & 0x1f) << (8 + 3)) | ((color & 0x1f) << 3); |
((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:6:5) */ |
static void rgb_byte565(void *dst, int rgb) |
/** RGB 5:5:5 conversion |
* |
*/ |
static void rgb_555(void *dst, uint32_t rgb) |
{ |
/* 5-bit, 6-bits, 5-bits */ |
*((uint16_t *) dst) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 | |
BLUE(rgb, 5); |
*((uint16_t *) dst) |
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 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 |
184,258 → 166,265 |
* 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(uint8_t glyph, unsigned int col, unsigned int row, bool silent) |
{ |
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); |
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) { |
uint8_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 + cols, cols * (rows - 1)); |
memsetb(&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)); |
glyph_draw(CURSOR, position % cols, position / cols, silent); |
} |
/** 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); |
glyph_draw(0, position % cols, position / cols, silent); |
} |
/***************************************************************/ |
/* 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, char 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((uint8_t) ' ', position % cols, |
position / cols, silent); |
position++; |
} while ((position % 8) && position < columns * rows); |
} while ((position % 8) && (position < cols * rows)); |
break; |
default: |
draw_char(ch); |
glyph_draw((uint8_t) ch, position % cols, |
position / cols, silent); |
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 */ |
unsigned int glyph; |
for (glyph = 0; glyph < FONT_GLYPHS; glyph++) { |
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[ROW2Y(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) { |
void *d = &fb_addr[FB_POS(x, y + yd)]; |
void *s = &glyphs[GLYPH_POS(backbuf[BB_POS(col, |
row)], yd)]; |
memcpy(d, s, 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 |
443,101 → 432,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; |
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; |
unsigned int fbsize = scanline * yres; |
unsigned int bbsize = cols * rows; |
unsigned int glyphsize = FONT_GLYPHS * glyphbytes; |
backbuf = (uint8_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."); |
memsetb(backbuf, bbsize, 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/network/kernel/genarch/src/fb/font-8x16.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
34,7 → 34,7 |
#include <genarch/fb/font-8x16.h> |
unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES] = { |
uint8_t fb_font[FONT_GLYPHS * FONT_SCANLINES] = { |
/* 0 0x00 '^@' */ |
0x00, /* 00000000 */ |
/branches/network/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 |
/branches/network/kernel/genarch/src/ofw/ebus.c |
---|
38,13 → 38,14 |
#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; |
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; |
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,10 → 118,12 |
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; |
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/network/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> |
67,7 → 67,7 |
return true; |
} |
if (strcmp(ofw_tree_node_name(node->parent), "central") != 0) |
panic("Unexpected parent node: %s.\n", ofw_tree_node_name(node->parent)); |
panic("Unexpected parent node: %s.", ofw_tree_node_name(node->parent)); |
ofw_central_reg_t central_reg; |
84,7 → 84,7 |
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; |
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/network/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,12 → 54,14 |
/** 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; |
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) |
{ |
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; |
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; |
202,15 → 211,41 |
} |
/** 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 (strcmp(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; |
236,8 → 271,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/network/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,7 → 49,8 |
#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; |
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 */ |
95,7 → 101,7 |
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/network/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,7 → 164,7 |
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); |
/branches/network/kernel/genarch/src/drivers/ns16550/ns16550.c |
---|
0,0 → 1,115 |
/* |
* 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 indev_operations_t kbrdin_ops = { |
.poll = NULL |
}; |
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 x = pio_read_8(&dev->rbr); |
indev_push_character(&instance->kbrdin, x); |
} |
} |
/** 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 device pointer or NULL on failure. |
* |
*/ |
indev_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) |
return NULL; |
indev_initialize("ns16550", &instance->kbrdin, &kbrdin_ops); |
instance->ns16550 = dev; |
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; |
irq_register(&instance->irq); |
while ((pio_read_8(&dev->lsr) & LSR_DATA_READY)) |
(void) pio_read_8(&dev->rbr); |
/* Enable interrupts */ |
pio_write_8(&dev->ier, IER_ERBFI); |
pio_write_8(&dev->mcr, MCR_OUT2); |
return &instance->kbrdin; |
} |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/network/kernel/genarch/src/drivers/dsrln/dsrlnin.c |
---|
0,0 → 1,83 |
/* |
* 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 indev_operations_t kbrdin_ops = { |
.poll = NULL |
}; |
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->kbrdin, pio_read_8(&dev->data)); |
} |
indev_t *dsrlnin_init(dsrlnin_t *dev, inr_t inr) |
{ |
dsrlnin_instance_t *instance |
= malloc(sizeof(dsrlnin_instance_t), FRAME_ATOMIC); |
if (!instance) |
return NULL; |
indev_initialize("dsrlnin", &instance->kbrdin, &kbrdin_ops); |
instance->dsrlnin = dev; |
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; |
irq_register(&instance->irq); |
return &instance->kbrdin; |
} |
/** @} |
*/ |
/branches/network/kernel/genarch/src/drivers/dsrln/dsrlnout.c |
---|
0,0 → 1,71 |
/* |
* 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> |
static ioport8_t *dsrlnout_base; |
static void dsrlnout_putchar(outdev_t *dev __attribute__((unused)), const char ch, bool silent) |
{ |
if (!silent) |
pio_write_8(dsrlnout_base, ch); |
} |
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/network/kernel/genarch/src/drivers/i8042/i8042.c |
---|
0,0 → 1,109 |
/* |
* 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> |
static indev_operations_t kbrdin_ops = { |
.poll = NULL |
}; |
#define i8042_SET_COMMAND 0x60 |
#define i8042_COMMAND 0x69 |
#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); |
} |
} |
/** Initialize i8042. */ |
indev_t *i8042_init(i8042_t *dev, inr_t inr) |
{ |
i8042_instance_t *instance |
= malloc(sizeof(i8042_instance_t), FRAME_ATOMIC); |
if (!instance) |
return NULL; |
indev_initialize("i8042", &instance->kbrdin, &kbrdin_ops); |
instance->i8042 = dev; |
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; |
irq_register(&instance->irq); |
/* |
* Clear input buffer. |
*/ |
while (pio_read_8(&dev->status) & i8042_BUFFER_FULL_MASK) |
(void) pio_read_8(&dev->data); |
return &instance->kbrdin; |
} |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/network/kernel/genarch/src/drivers/z8530/z8530.c |
---|
0,0 → 1,133 |
/* |
* 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 indev_operations_t kbrdin_ops = { |
.poll = NULL |
}; |
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 x = z8530_read(&dev->ctl_a, RR8); |
indev_push_character(&instance->kbrdin, x); |
} |
} |
/** Initialize z8530. */ |
indev_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) |
return false; |
indev_initialize("z8530", &instance->kbrdin, &kbrdin_ops); |
instance->z8530 = dev; |
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; |
irq_register(&instance->irq); |
(void) z8530_read(&dev->ctl_a, RR8); |
/* |
* Clear any pending TX interrupts or we never manage |
* to set FHC UART interrupt state to idle. |
*/ |
z8530_write(&dev->ctl_a, WR0, WR0_TX_IP_RST); |
/* interrupt on all characters */ |
z8530_write(&dev->ctl_a, WR1, WR1_IARCSC); |
/* 8 bits per character and enable receiver */ |
z8530_write(&dev->ctl_a, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE); |
/* Master Interrupt Enable. */ |
z8530_write(&dev->ctl_a, WR9, WR9_MIE); |
return &instance->kbrdin; |
} |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/network/kernel/genarch/src/drivers/ega/ega.c |
---|
0,0 → 1,206 |
/* |
* 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 <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 0x07 |
#define EMPTY_CHAR (STYLE << 8 | SPACE) |
/* |
* This function takes care of scrolling. |
*/ |
static void ega_check_cursor(void) |
{ |
if (ega_cursor < EGA_SCREEN) |
return; |
memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2), |
(EGA_SCREEN - EGA_COLS) * 2); |
memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2), |
(EGA_SCREEN - EGA_COLS) * 2); |
memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); |
memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); |
ega_cursor = ega_cursor - EGA_COLS; |
} |
static void ega_show_cursor(void) |
{ |
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(void) |
{ |
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(void) |
{ |
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; |
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(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR); |
memsetw(backbuf + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR); |
ega_check_cursor(); |
ega_move_cursor(); |
ega_show_cursor(); |
} |
static void ega_display_char(char ch, bool silent) |
{ |
backbuf[ega_cursor * 2] = ch; |
backbuf[ega_cursor * 2 + 1] = STYLE; |
if (!silent) { |
videoram[ega_cursor * 2] = ch; |
videoram[ega_cursor * 2 + 1] = STYLE; |
} |
} |
static void ega_putchar(outdev_t *dev __attribute__((unused)), const char 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(); |
if (!silent) |
ega_move_cursor(); |
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(); |
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(); |
ega_show_cursor(); |
} |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/network/kernel/genarch/src/multiboot/multiboot.c |
---|
0,0 → 1,148 |
/* |
* 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 n Size of destination buffer. |
* @param cmd_line Input string (the command line). |
* |
*/ |
static void extract_command(char *buf, size_t n, const char *cmd_line) |
{ |
const char *start, *end, *cp; |
size_t max_len; |
/* Find the first space. */ |
end = strchr(cmd_line, ' '); |
if (end == NULL) |
end = cmd_line + strlen(cmd_line); |
/* |
* Find last occurence of '/' before 'end'. If found, place start at |
* next character. Otherwise, place start at beginning of buffer. |
*/ |
cp = end; |
start = buf; |
while (cp != start) { |
if (*cp == '/') { |
start = cp + 1; |
break; |
} |
--cp; |
} |
/* Copy the command and null-terminate the string. */ |
max_len = min(n - 1, (size_t) (end - start)); |
strncpy(buf, start, max_len + 1); |
buf[max_len] = '\0'; |
} |
/** 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; |
multiboot_mod_t *mods; |
uint32_t i; |
if (signature == MULTIBOOT_LOADER_MAGIC) |
flags = mi->flags; |
else { |
/* No multiboot info available. */ |
flags = 0; |
} |
/* Copy module information. */ |
if ((flags & MBINFO_FLAGS_MODS) != 0) { |
init.cnt = mi->mods_count; |
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. */ |
int32_t mmap_length; |
multiboot_mmap_t *mme; |
uint32_t size; |
if ((flags & MBINFO_FLAGS_MMAP) != 0) { |
mmap_length = mi->mmap_length; |
mme = MULTIBOOT_PTR(mi->mmap_addr); |
e820counter = 0; |
i = 0; |
while (mmap_length > 0) { |
e820table[i++] = mme->mm_info; |
/* Compute address of next structure. */ |
size = sizeof(mme->size) + mme->size; |
mme = ((void *) mme) + size; |
mmap_length -= size; |
} |
e820counter = i; |
} else |
e820counter = 0; |
} |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/network/kernel/genarch/src/srln/srln.c |
---|
0,0 → 1,88 |
/* |
* 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> |
static indev_t srlnout; |
indev_operations_t srlnout_ops = { |
.poll = NULL |
}; |
static void ksrln(void *arg) |
{ |
indev_t *in = (indev_t *) arg; |
bool cr = false; |
while (true) { |
uint8_t ch = _getc(in); |
if ((ch == '\n') && (cr)) { |
cr = false; |
continue; |
} |
if (ch == '\r') { |
ch = '\n'; |
cr = true; |
} else |
cr = false; |
if (ch == 0x7f) |
ch = '\b'; |
indev_push_character(stdin, ch); |
} |
} |
void srln_init(indev_t *devin) |
{ |
indev_initialize("srln", &srlnout, &srlnout_ops); |
thread_t *thread |
= thread_create(ksrln, devin, TASK, 0, "ksrln", false); |
if (thread) { |
stdin = &srlnout; |
thread_ready(thread); |
} |
} |
/** @} |
*/ |
/branches/network/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/network/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/network/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/network/kernel/generic/include/byteorder.h |
---|
51,6 → 51,14 |
#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) |
61,6 → 69,14 |
#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/network/kernel/generic/include/symtab.h |
---|
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); |
#ifdef CONFIG_SYMTAB |
/* Symtable linked together by build process */ |
extern struct symtab_entry symbol_table[]; |
#endif |
#endif |
/** @} |
*/ |
/branches/network/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,13 → 38,16 |
#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 { |
63,14 → 66,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. */ |
count_t cpu_count; /**< Number of processors detected. */ |
volatile count_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/network/kernel/generic/include/string.h |
---|
0,0 → 1,50 |
/* |
* 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 <arch/types.h> |
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 char *strchr(const char *s, int i); |
#endif |
/** @} |
*/ |
/branches/network/kernel/generic/include/proc/task.h |
---|
52,7 → 52,11 |
#include <arch/cpu.h> |
#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. */ |
66,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. */ |
93,7 → 97,15 |
* certain extent. |
*/ |
atomic_t active_calls; |
#ifdef CONFIG_UDEBUG |
/** Debugging stuff. */ |
udebug_task_t udebug; |
/** Kernel answerbox. */ |
kbox_t kb; |
#endif |
/** Architecture specific task data. */ |
task_arch_t arch; |
132,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/network/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/network/kernel/generic/include/proc/thread.h |
---|
46,6 → 46,7 |
#include <arch/cpu.h> |
#include <mm/tlb.h> |
#include <proc/uarg.h> |
#include <udebug/udebug.h> |
#define THREAD_STACK_SIZE STACK_SIZE |
#define THREAD_NAME_BUFLEN 20 |
203,6 → 204,12 |
/** Thread's kernel stack. */ |
uint8_t *kstack; |
#ifdef CONFIG_UDEBUG |
/** Debugging stuff */ |
udebug_thread_t udebug; |
#endif |
} thread_t; |
/** Thread list lock. |
252,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/network/kernel/generic/include/udebug/udebug.h |
---|
0,0 → 1,210 |
/* |
* Copyright (c) 2008 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 generic |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_UDEBUG_H_ |
#define KERN_UDEBUG_H_ |
#include <ipc/ipc.h> |
typedef enum { /* udebug_method_t */ |
/** Start debugging the recipient. |
* Causes all threads in the receiving task to stop. When they |
* are all stoped, an answer with retval 0 is generated. |
*/ |
UDEBUG_M_BEGIN = 1, |
/** Finish debugging the recipient. |
* Answers all pending GO and GUARD messages. |
*/ |
UDEBUG_M_END, |
/** Set which events should be captured. |
*/ |
UDEBUG_M_SET_EVMASK, |
/** Make sure the debugged task is still there. |
* This message is answered when the debugged task dies |
* or the debugging session ends. |
*/ |
UDEBUG_M_GUARD, |
/** Run a thread until a debugging event occurs. |
* This message is answered when the thread stops |
* in a debugging event. |
* |
* - ARG2 - id of the thread to run |
*/ |
UDEBUG_M_GO, |
/** Stop a thread being debugged. |
* Creates a special STOP event in the thread, causing |
* it to answer a pending GO message (if any). |
*/ |
UDEBUG_M_STOP, |
/** Read arguments of a syscall. |
* |
* - ARG2 - thread identification |
* - ARG3 - destination address in the caller's address space |
* |
*/ |
UDEBUG_M_ARGS_READ, |
/** Read the list of the debugged tasks's threads. |
* |
* - ARG2 - destination address in the caller's address space |
* - ARG3 - size of receiving buffer in bytes |
* |
* The kernel fills the buffer with a series of sysarg_t values |
* (thread ids). On answer, the kernel will set: |
* |
* - ARG2 - number of bytes that were actually copied |
* - ARG3 - number of bytes of the complete data |
* |
*/ |
UDEBUG_M_THREAD_READ, |
/** Read the debugged tasks's memory. |
* |
* - ARG2 - destination address in the caller's address space |
* - ARG3 - source address in the recipient's address space |
* - ARG4 - size of receiving buffer in bytes |
* |
*/ |
UDEBUG_M_MEM_READ, |
} udebug_method_t; |
typedef enum { |
UDEBUG_EVENT_FINISHED = 1, /**< Debuging session has finished */ |
UDEBUG_EVENT_STOP, /**< Stopped on DEBUG_STOP request */ |
UDEBUG_EVENT_SYSCALL_B, /**< Before beginning syscall execution */ |
UDEBUG_EVENT_SYSCALL_E, /**< After finishing syscall execution */ |
UDEBUG_EVENT_THREAD_B, /**< The task created a new thread */ |
UDEBUG_EVENT_THREAD_E /**< A thread exited */ |
} udebug_event_t; |
#define UDEBUG_EVMASK(event) (1 << ((event) - 1)) |
typedef enum { |
UDEBUG_EM_FINISHED = UDEBUG_EVMASK(UDEBUG_EVENT_FINISHED), |
UDEBUG_EM_STOP = UDEBUG_EVMASK(UDEBUG_EVENT_STOP), |
UDEBUG_EM_SYSCALL_B = UDEBUG_EVMASK(UDEBUG_EVENT_SYSCALL_B), |
UDEBUG_EM_SYSCALL_E = UDEBUG_EVMASK(UDEBUG_EVENT_SYSCALL_E), |
UDEBUG_EM_THREAD_B = UDEBUG_EVMASK(UDEBUG_EVENT_THREAD_B), |
UDEBUG_EM_THREAD_E = UDEBUG_EVMASK(UDEBUG_EVENT_THREAD_E), |
UDEBUG_EM_ALL = |
UDEBUG_EVMASK(UDEBUG_EVENT_FINISHED) | |
UDEBUG_EVMASK(UDEBUG_EVENT_STOP) | |
UDEBUG_EVMASK(UDEBUG_EVENT_SYSCALL_B) | |
UDEBUG_EVMASK(UDEBUG_EVENT_SYSCALL_E) | |
UDEBUG_EVMASK(UDEBUG_EVENT_THREAD_B) | |
UDEBUG_EVMASK(UDEBUG_EVENT_THREAD_E) |
} udebug_evmask_t; |
#ifdef KERNEL |
#include <synch/mutex.h> |
#include <arch/interrupt.h> |
#include <atomic.h> |
typedef enum { |
/** Task is not being debugged */ |
UDEBUG_TS_INACTIVE, |
/** BEGIN operation in progress (waiting for threads to stop) */ |
UDEBUG_TS_BEGINNING, |
/** Debugger fully connected */ |
UDEBUG_TS_ACTIVE |
} udebug_task_state_t; |
/** Debugging part of task_t structure. |
*/ |
typedef struct { |
/** Synchronize debug ops on this task / access to this structure */ |
mutex_t lock; |
char *lock_owner; |
udebug_task_state_t dt_state; |
call_t *begin_call; |
int not_stoppable_count; |
struct task *debugger; |
udebug_evmask_t evmask; |
} udebug_task_t; |
/** Debugging part of thread_t structure. |
*/ |
typedef struct { |
/** 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 go; /**< thread is GO */ |
bool stoppable; /**< thread is stoppable */ |
bool active; /**< thread is in a debugging session */ |
} udebug_thread_t; |
struct task; |
struct thread; |
void udebug_task_init(udebug_task_t *ut); |
void udebug_thread_initialize(udebug_thread_t *ut); |
void udebug_syscall_event(unative_t a1, unative_t a2, unative_t a3, |
unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc, |
bool end_variant); |
void udebug_thread_b_event_attach(struct thread *t, struct task *ta); |
void udebug_thread_e_event(void); |
void udebug_stoppable_begin(void); |
void udebug_stoppable_end(void); |
void udebug_before_thread_runs(void); |
int udebug_task_cleanup(struct task *ta); |
#endif |
#endif |
/** @} |
*/ |
/branches/network/kernel/generic/include/udebug/udebug_ops.h |
---|
0,0 → 1,55 |
/* |
* Copyright (c) 2008 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 generic |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_UDEBUG_OPS_H_ |
#define KERN_UDEBUG_OPS_H_ |
#include <ipc/ipc.h> |
int udebug_begin(call_t *call); |
int udebug_end(void); |
int udebug_set_evmask(udebug_evmask_t mask); |
int udebug_go(thread_t *t, call_t *call); |
int udebug_stop(thread_t *t, call_t *call); |
int udebug_thread_read(void **buffer, size_t buf_size, size_t *n); |
int udebug_args_read(thread_t *t, void **buffer); |
int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer); |
#endif |
/** @} |
*/ |
/branches/network/kernel/generic/include/udebug/udebug_ipc.h |
---|
0,0 → 1,47 |
/* |
* Copyright (c) 2008 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 generic |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_UDEBUG_IPC_H_ |
#define KERN_UDEBUG_IPC_H_ |
#include <ipc/ipc.h> |
int udebug_request_preprocess(call_t *call, phone_t *phone); |
void udebug_call_receive(call_t *call); |
#endif |
/** @} |
*/ |
/branches/network/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/network/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/network/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/network/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/network/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> |
/branches/network/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/network/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,6 → 99,8 |
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. */ |
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(count_t, count_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/network/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/network/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/network/kernel/generic/include/console/chardev.h |
---|
39,41 → 39,60 |
#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; |
char (* 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]; |
SPINLOCK_DECLARE(lock); |
uint8_t buffer[INDEV_BUFLEN]; |
count_t counter; |
/** Implementation of chardev operations. */ |
chardev_operations_t *op; |
/** Implementation of indev operations. */ |
indev_operations_t *op; |
index_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 *, char c, bool silent); |
} 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, uint8_t ch); |
extern void outdev_initialize(char *name, outdev_t *outdev, |
outdev_operations_t *op); |
#endif /* KERN_CHARDEV_H_ */ |
/** @} |
/branches/network/kernel/generic/include/console/kconsole.h |
---|
37,6 → 37,7 |
#include <adt/list.h> |
#include <synch/spinlock.h> |
#include <ipc/irq.h> |
#define MAX_CMDLINE 256 |
#define KCONSOLE_HISTORY 10 |
83,11 → 84,17 |
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); |
/branches/network/kernel/generic/include/console/console.h |
---|
38,17 → 38,29 |
#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 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 bool check_poll(indev_t *indev); |
extern uint8_t getc(indev_t *indev); |
extern uint8_t _getc(indev_t *indev); |
extern count_t gets(indev_t *indev, char *buf, size_t buflen); |
extern void putchar(char c); |
extern unative_t sys_klog(int fd, const void * buf, size_t count); |
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/network/kernel/generic/include/arch.h |
---|
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/network/kernel/generic/include/adt/bitmap.h |
---|
49,6 → 49,14 |
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); |
static inline int bitmap_get(bitmap_t *bitmap,index_t bit) |
{ |
if(bit >= bitmap->bits) |
return 0; |
return !! ((bitmap->map)[bit/8] & (1 << (bit & 7))); |
} |
#endif |
/** @} |
/branches/network/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 { |
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; |
typedef struct { |
pfn_t base; /**< Frame_no of the first frame |
in the frames array */ |
count_t count; /**< Size of zone */ |
count_t free_count; /**< Number of free frame_t |
structures */ |
count_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); |
count_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); |
88,31 → 136,37 |
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, count_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 count_t find_zone(pfn_t frame, count_t count, count_t hint); |
extern count_t zone_create(pfn_t, count_t, pfn_t, zone_flags_t); |
extern void *frame_get_parent(pfn_t, count_t); |
extern void frame_set_parent(pfn_t, void *, count_t); |
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 bool zone_merge(count_t, count_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(count_t); |
#endif |
/branches/network/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/network/kernel/generic/include/mm/slab.h |
---|
59,7 → 59,7 |
/* 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 */ |
/branches/network/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/network/kernel/generic/include/typedefs.h |
---|
51,6 → 51,10 |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
#endif |
/** @} |
/branches/network/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,66 |
#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 |
/** 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/network/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/network/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,6 → 63,7 |
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, |
70,6 → 72,7 |
SYS_CAP_GRANT, |
SYS_CAP_REVOKE, |
SYS_DEVICE_ASSIGN_DEVNO, |
SYS_PHYSMEM_MAP, |
SYS_IOSPACE_ENABLE, |
SYS_PREEMPT_CONTROL, |
78,6 → 81,8 |
SYS_SYSINFO_VALUE, |
SYS_DEBUG_ENABLE_CONSOLE, |
SYS_DEBUG_DISABLE_CONSOLE, |
SYS_IPC_CONNECT_KBOX, |
SYSCALL_END |
} syscall_t; |
/branches/network/kernel/generic/include/ipc/sysipc.h |
---|
53,10 → 53,13 |
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); |
unative_t sys_ipc_unregister_irq(inr_t inr, devno_t devno); |
unative_t sys_ipc_connect_kbox(sysarg64_t *task_id); |
#endif |
/branches/network/kernel/generic/include/ipc/ipc.h |
---|
195,6 → 195,12 |
*/ |
#define IPC_M_DATA_READ 7 |
/** 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 |
/* Well-known methods */ |
#define IPC_M_LAST_SYSTEM 511 |
#define IPC_M_PING 512 |
260,12 → 266,6 |
typedef struct { |
unative_t args[IPC_CALL_LEN]; |
phone_t *phone; |
/* |
* The forward operation can masquerade the caller phone. For those |
* cases, we must keep it aside so that the answer is processed |
* correctly. |
*/ |
phone_t *caller_phone; |
} ipc_data_t; |
typedef struct { |
287,6 → 287,13 |
/** Buffer for IPC_M_DATA_WRITE and IPC_M_DATA_READ. */ |
uint8_t *buffer; |
/* |
* The forward operation can masquerade the caller phone. For those |
* cases, we must keep it aside so that the answer is processed |
* correctly. |
*/ |
phone_t *caller_phone; |
} call_t; |
extern void ipc_init(void); |
306,6 → 313,8 |
extern int ipc_phone_hangup(phone_t *); |
extern void ipc_backsend_err(phone_t *, call_t *, unative_t); |
extern void ipc_print_task(task_id_t); |
extern void ipc_answerbox_slam_phones(answerbox_t *, bool); |
extern void ipc_cleanup_call_list(link_t *); |
extern answerbox_t *ipc_phone_0; |
/branches/network/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/network/kernel/generic/include/ipc/kbox.h |
---|
0,0 → 1,58 |
/* |
* Copyright (c) 2008 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 genericipc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_IPC_KBOX_H_ |
#define KERN_IPC_KBOX_H_ |
#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); |
#endif |
/** @} |
*/ |
/branches/network/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/network/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/network/kernel/generic/src/synch/spinlock.c |
---|
76,7 → 76,6 |
void spinlock_lock_debug(spinlock_t *sl) |
{ |
count_t i = 0; |
char *symbol; |
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)", CPU->id, sl, sl->name, |
CALLER, symtab_fmt_name_lookup(CALLER)); |
i = 0; |
deadlock_reported = true; |
} |
/branches/network/kernel/generic/src/synch/futex.c |
---|
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. |
/branches/network/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,24 → 114,18 |
* 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; |
125,35 → 133,36 |
* 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" PRIc "\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(); |
/* |
164,14 → 173,31 |
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[%" PRIc "].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); |
strncpy(namebuf, INIT_PREFIX, TASK_NAME_BUFLEN); |
strncpy(namebuf + INIT_PREFIX_LEN, name, |
TASK_NAME_BUFLEN - INIT_PREFIX_LEN); |
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,42 |
/* 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 %" PRIc " not used (error %d)\n", i, rd); |
} |
} |
/* |
* Run user tasks with reasonable delays |
* Run user tasks with small delays |
* to avoid intermixed klog output. |
* |
* TODO: This certainly does not guarantee |
* anything, it just works in most of the |
* cases. Some better way how to achieve |
* nice klog output should be found. |
*/ |
for (i = 0; i < init.cnt; i++) { |
if (programs[i].task != NULL) { |
thread_usleep(50000); |
program_ready(&programs[i]); |
thread_usleep(10000); |
} |
} |
#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/network/kernel/generic/src/main/main.c |
---|
81,8 → 81,8 |
#include <adt/btree.h> |
#include <smp/smp.h> |
#include <ddi/ddi.h> |
#include <main/main.h> |
/** Global configuration structure. */ |
config_t config; |
105,18 → 105,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 |
191,8 → 188,6 |
{ |
/* Keep this the first thing. */ |
the_initialize(THE); |
LOG(); |
version_print(); |
201,7 → 196,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 → 203,7 |
* commands. |
*/ |
LOG_EXEC(kconsole_init()); |
#endif |
/* |
* Exception handler initialization, before architecture |
214,7 → 210,7 |
* starts adding its own handlers |
*/ |
LOG_EXEC(exc_init()); |
/* |
* Memory management subsystems initialization. |
*/ |
252,7 → 248,7 |
if (init.cnt > 0) { |
count_t i; |
for (i = 0; i < init.cnt; i++) |
printf("init[%" PRIc "].addr=%#" PRIp ", init[%" PRIc |
LOG("init[%" PRIc "].addr=%#" PRIp ", init[%" PRIc |
"].size=%#" PRIs "\n", i, init.tasks[i].addr, i, |
init.tasks[i].size); |
} else |
260,21 → 256,25 |
LOG_EXEC(ipc_init()); |
LOG_EXEC(klog_init()); |
#ifdef CONFIG_KCONSOLE |
LOG_EXEC(kconsole_notify_init()); |
#endif |
/* |
* 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 → 328,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/network/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-2008 HelenOS project"; |
char *release = RELEASE; |
char *name = NAME; |
char *arch = ARCH; |
char *copyright = "Copyright (c) 2001-2009 HelenOS project"; |
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/network/kernel/generic/src/main/uinit.c |
---|
46,7 → 46,9 |
#include <userspace.h> |
#include <mm/slab.h> |
#include <arch.h> |
#include <udebug/udebug.h> |
/** Thread used to bring up userspace thread. |
* |
* @param arg Pointer to structure containing userspace entry and stack |
65,6 → 67,10 |
* deployed for the event of forceful task termination. |
*/ |
thread_detach(THREAD); |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_end(); |
#endif |
uarg.uspace_entry = ((uspace_arg_t *) arg)->uspace_entry; |
uarg.uspace_stack = ((uspace_arg_t *) arg)->uspace_stack; |
/branches/network/kernel/generic/src/debug/symtab.c |
---|
37,22 → 37,23 |
#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 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. |
* |
* @param addr Address. |
* |
* @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) |
{ |
#ifdef CONFIG_SYMTAB |
count_t i; |
for (i = 1; symbol_table[i].address_le; ++i) { |
59,11 → 60,44 |
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 |
} |
/** Lookup symbol by address and format for display. |
* |
* 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. |
*/ |
char *symtab_fmt_name_lookup(unative_t addr) |
{ |
int rc; |
char *name; |
rc = symtab_name_lookup(addr, &name); |
switch (rc) { |
case EOK: return name; |
case ENOENT: return "Not found"; |
default: return "N/A"; |
} |
} |
#ifdef CONFIG_SYMTAB |
/** Find symbols that match the parameter forward and print them. |
* |
* @param name - search string |
102,17 → 136,22 |
return NULL; |
} |
#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 name Name of the 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) |
{ |
#ifdef CONFIG_SYMTAB |
count_t found = 0; |
uintptr_t addr = NULL; |
char *hint; |
int i; |
119,19 → 158,25 |
i = 0; |
while ((hint = symtab_search_one(name, &i))) { |
if (!strlen(hint)) { |
addr = uint64_t_le2host(symbol_table[i].address_le); |
*addr = uint64_t_le2host(symbol_table[i].address_le); |
found++; |
} |
i++; |
} |
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 */ |
void symtab_print_search(const char *name) |
{ |
#ifdef CONFIG_SYMTAB |
int i; |
uintptr_t addr; |
char *realname; |
144,6 → 189,9 |
printf("%p: %s\n", addr, realname); |
i++; |
} |
#else |
printf("No symbol information available.\n"); |
#endif |
} |
/** Symtab completion |
153,6 → 201,7 |
*/ |
int symtab_compl(char *input) |
{ |
#ifdef CONFIG_SYMTAB |
char output[MAX_SYMBOL_NAME + 1]; |
int startpos = 0; |
char *foundtxt; |
196,7 → 245,9 |
} |
strncpy(input, output, MAX_SYMBOL_NAME); |
return found; |
#else |
return 0; |
#endif |
} |
/** @} |
/branches/network/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/network/kernel/generic/src/sysinfo/sysinfo.c |
---|
163,7 → 163,8 |
i = 0; |
} |
} |
panic("Not reached\n"); |
panic("Not reached."); |
return NULL; |
} |
/branches/network/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); |
_getc(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/network/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/network/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); |
/* |
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/network/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/network/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) |
{ |
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); |
count_t znum = find_zone(ADDR2PFN(pf), pages, 0); |
if (znum == (count_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,7 → 235,8 |
* @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) |
{ |
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/network/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,13 → 80,22 |
#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. |
*/ |
110,6 → 123,9 |
.remove_callback = NULL /* not used */ |
}; |
/** Number of buckets in either of the hash tables. */ |
static count_t buckets; |
/** Initialize IRQ subsystem. |
* |
* @param inrs Numbers of unique IRQ numbers or INRs. |
117,6 → 133,7 |
*/ |
void irq_init(count_t inrs, count_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 → 140,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 → 160,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 → 172,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 → 186,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. |
270,7 → 299,7 |
index_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. |
304,7 → 333,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)); |
363,7 → 393,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); |
/branches/network/kernel/generic/src/printf/vprintf.c |
---|
62,13 → 62,13 |
{ |
struct printf_spec ps = {(int(*)(void *, size_t, void *)) vprintf_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/network/kernel/generic/src/printf/printf_core.c |
---|
40,7 → 40,7 |
#include <print.h> |
#include <arch/arg.h> |
#include <macros.h> |
#include <func.h> |
#include <string.h> |
#include <arch.h> |
/** show prefixes 0x or 0 */ |
/branches/network/kernel/generic/src/console/console.c |
---|
39,7 → 39,6 |
#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/irq.h> |
47,71 → 46,45 |
#include <func.h> |
#include <print.h> |
#include <atomic.h> |
#include <syscall/copy.h> |
#include <errno.h> |
#define KLOG_SIZE PAGE_SIZE |
#define KLOG_LATENCY 8 |
/**< Kernel log cyclic buffer */ |
/** Kernel log cyclic buffer */ |
static char klog[KLOG_SIZE] __attribute__ ((aligned (PAGE_SIZE))); |
/**< Kernel log initialized */ |
/** Kernel log initialized */ |
static bool klog_inited = false; |
/**< First kernel log characters */ |
/** First kernel log characters */ |
static index_t klog_start = 0; |
/**< Number of valid kernel log characters */ |
/** 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 */ |
/** Silence output */ |
bool silent = false; |
/** 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; |
/** Standard input and output character devices */ |
indev_t *stdin = NULL; |
outdev_t *stdout = NULL; |
static chardev_operations_t null_stdout_ops = { |
.suspend = NULL, |
.resume = NULL, |
.write = NULL, |
.read = NULL |
}; |
chardev_t null_stdout = { |
.name = "null", |
.op = &null_stdout_ops |
}; |
/** 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) |
{ |
return IRQ_DECLINE; |
} |
/** 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) |
{ |
119,89 → 92,122 |
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; |
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); |
//irq_initialize(&klog_irq); |
//klog_irq.devno = devno; |
//klog_irq.inr = KLOG_VIRT_INR; |
//klog_irq.claim = klog_claim; |
//irq_register(&klog_irq); |
spinlock_lock(&klog_lock); |
klog_inited = true; |
spinlock_unlock(&klog_lock); |
} |
/** Get character from character device. Do not echo character. |
void grab_console(void) |
{ |
silent = false; |
arch_grab_console(); |
} |
void release_console(void) |
{ |
silent = true; |
arch_release_console(); |
} |
/** 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 |
} |
/** Tell kernel to relinquish keyboard/console access */ |
unative_t sys_debug_disable_console(void) |
{ |
release_console(); |
return true; |
} |
bool check_poll(indev_t *indev) |
{ |
if (indev == NULL) |
return false; |
if (indev->op == NULL) |
return false; |
return (indev->op->poll != NULL); |
} |
/** Get character from input character device. Do not echo character. |
* |
* @param chardev Character device. |
* @param indev Input character device. |
* @return Character read. |
* |
* @return Character read. |
*/ |
uint8_t _getc(chardev_t *chardev) |
uint8_t _getc(indev_t *indev) |
{ |
uint8_t ch; |
ipl_t ipl; |
if (atomic_get(&haltstate)) { |
/* If we are here, we are hopefully on the processor, that |
/* 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 (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 kconsole\n"); |
printf("halted (no polling input)\n"); |
cpu_halt(); |
} |
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); |
waitq_sleep(&indev->wq); |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&indev->lock); |
uint8_t ch = indev->buffer[(indev->index - indev->counter) % INDEV_BUFLEN]; |
indev->counter--; |
spinlock_unlock(&indev->lock); |
interrupts_restore(ipl); |
chardev->op->resume(chardev); |
return ch; |
} |
/** 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 '\0'. |
* @param buflen Size of the buffer. |
* |
* @return Number of characters read. |
* |
*/ |
count_t gets(chardev_t *chardev, char *buf, size_t buflen) |
count_t gets(indev_t *indev, char *buf, size_t buflen) |
{ |
index_t index = 0; |
char ch; |
while (index < buflen) { |
ch = _getc(chardev); |
char ch = _getc(indev); |
if (ch == '\b') { |
if (index > 0) { |
index--; |
213,7 → 219,7 |
continue; |
} |
putchar(ch); |
if (ch == '\n') { /* end of string => write 0, return */ |
buf[index] = '\0'; |
return (count_t) index; |
220,15 → 226,14 |
} |
buf[index++] = ch; |
} |
return (count_t) index; |
} |
/** Get character from device & echo it to screen */ |
uint8_t getc(chardev_t *chardev) |
/** Get character from input device & echo it to screen */ |
uint8_t getc(indev_t *indev) |
{ |
uint8_t ch; |
ch = _getc(chardev); |
uint8_t ch = _getc(indev); |
putchar(ch); |
return ch; |
} |
237,10 → 242,10 |
{ |
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); |
klog_uspace = 0; |
} |
// if ((klog_inited) && (klog_irq.notif_cfg.notify) && (klog_uspace > 0)) { |
// ipc_irq_send_msg_3(&klog_irq, klog_start, klog_len, klog_uspace); |
// klog_uspace = 0; |
// } |
spinlock_unlock(&klog_lock); |
} |
249,11 → 254,11 |
{ |
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; |
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_SIZE], silent); |
klog_stored = 0; |
} |
264,8 → 269,8 |
else |
klog_start = (klog_start + 1) % KLOG_SIZE; |
if (stdout->op->write) |
stdout->op->write(stdout, c); |
if ((stdout) && (stdout->op->write)) |
stdout->op->write(stdout, c, silent); |
else { |
/* The character is just in the kernel log */ |
if (klog_stored < klog_len) |
289,5 → 294,38 |
klog_update(); |
} |
/** Print using kernel facility |
* |
* Print to kernel log. |
* |
*/ |
unative_t sys_klog(int fd, const void * buf, size_t count) |
{ |
char *data; |
int rc; |
if (count > PAGE_SIZE) |
return ELIMIT; |
if (count > 0) { |
data = (char *) malloc(count + 1, 0); |
if (!data) |
return ENOMEM; |
rc = copy_from_uspace(data, buf, count); |
if (rc) { |
free(data); |
return rc; |
} |
data[count] = 0; |
printf("%s", data); |
free(data); |
} else |
klog_update(); |
return count; |
} |
/** @} |
*/ |
/branches/network/kernel/generic/src/console/cmd.c |
---|
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,8 |
#include <proc/task.h> |
#include <ipc/ipc.h> |
#include <ipc/irq.h> |
#include <symtab.h> |
#include <errno.h> |
#ifdef CONFIG_TEST |
#include <test.h> |
78,12 → 80,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", |
398,17 → 394,17 |
.argc = 0 |
}; |
/* Data and methods for 'ipc_task' command */ |
static int cmd_ipc_task(cmd_arg_t *argv); |
static cmd_arg_t ipc_task_argv = { |
/* Data and methods for 'ipc' command */ |
static int cmd_ipc(cmd_arg_t *argv); |
static cmd_arg_t ipc_argv = { |
.type = ARG_TYPE_INT, |
}; |
static cmd_info_t ipc_task_info = { |
.name = "ipc_task", |
.description = "ipc_task <taskid> Show IPC information of given task.", |
.func = cmd_ipc_task, |
static cmd_info_t ipc_info = { |
.name = "ipc", |
.description = "ipc <taskid> Show IPC information of given task.", |
.func = cmd_ipc, |
.argc = 1, |
.argv = &ipc_task_argv |
.argv = &ipc_argv |
}; |
/* Data and methods for 'zone' command */ |
456,12 → 452,11 |
&continue_info, |
&cpus_info, |
&desc_info, |
&exit_info, |
&reboot_info, |
&uptime_info, |
&halt_info, |
&help_info, |
&ipc_task_info, |
&ipc_info, |
&set4_info, |
&slabs_info, |
&symaddr_info, |
501,7 → 496,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 → 509,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 (strlen(hlp->name) > len) |
len = strlen(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; |
} |
616,33 → 619,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; |
} |
680,35 → 676,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 → 705,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 → 735,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 → 807,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; |
937,7 → 913,7 |
* |
* return Always 1 |
*/ |
int cmd_ipc_task(cmd_arg_t * argv) { |
int cmd_ipc(cmd_arg_t * argv) { |
ipc_print_task(argv[0].intval); |
return 1; |
} |
976,8 → 952,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(); |
if ((kconsole_notify) && (kconsole_irq.notif_cfg.notify)) |
ipc_irq_send_msg_0(&kconsole_irq); |
return 1; |
} |
990,18 → 969,23 |
*/ |
int cmd_tests(cmd_arg_t *argv) |
{ |
size_t len = 0; |
test_t *test; |
for (test = tests; test->name != NULL; test++) { |
if (strlen(test->name) > len) |
len = strlen(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 */ |
/branches/network/kernel/generic/src/console/chardev.c |
---|
37,42 → 37,62 |
#include <synch/waitq.h> |
#include <synch/spinlock.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, uint8_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); |
} |
/** 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; |
} |
/** @} |
*/ |
/branches/network/kernel/generic/src/console/kconsole.c |
---|
49,8 → 49,12 |
#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> |
/** Simple kernel console. |
* |
83,10 → 87,39 |
index_t *end); |
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {}; |
/** Initialize kconsole data structures. */ |
/* |
* For now, we use 0 as INR. |
* However, it is therefore desirable to have architecture specific |
* definition of KCONSOLE_VIRT_INR in the future. |
*/ |
#define KCONSOLE_VIRT_INR 0 |
bool kconsole_notify = false; |
irq_t kconsole_irq; |
/** Allways refuse IRQ ownership. |
* |
* This is not a real IRQ, so we always decline. |
* |
* @return Always returns IRQ_DECLINE. |
* |
*/ |
static irq_ownership_t kconsole_claim(irq_t *irq) |
{ |
return IRQ_DECLINE; |
} |
/** 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++) |
94,6 → 127,26 |
} |
/** Initialize kconsole notification mechanism |
* |
* Initialize the virtual IRQ notification mechanism. |
* |
*/ |
void kconsole_notify_init(void) |
{ |
sysinfo_set_item_val("kconsole.present", NULL, true); |
sysinfo_set_item_val("kconsole.inr", NULL, KCONSOLE_VIRT_INR); |
irq_initialize(&kconsole_irq); |
kconsole_irq.devno = device_assign_devno(); |
kconsole_irq.inr = KCONSOLE_VIRT_INR; |
kconsole_irq.claim = kconsole_claim; |
irq_register(&kconsole_irq); |
kconsole_notify = true; |
} |
/** Register kconsole command. |
* |
* @param cmd Structure describing the command. |
203,7 → 256,7 |
*/ |
static int cmdtab_compl(char *name) |
{ |
static char output[MAX_SYMBOL_NAME + 1]; |
static char output[/*MAX_SYMBOL_NAME*/128 + 1]; |
link_t *startpos = NULL; |
const char *foundtxt; |
int found = 0; |
235,12 → 288,11 |
startpos = startpos->next; |
} |
} |
strncpy(name, output, MAX_SYMBOL_NAME); |
strncpy(name, output, 128/*MAX_SYMBOL_NAME*/); |
return found; |
} |
static char *clever_readline(const char *prompt, chardev_t *input) |
static char *clever_readline(const char *prompt, indev_t *input) |
{ |
static int histposition = 0; |
401,42 → 453,71 |
return current; |
} |
/** Kernel console managing thread. |
bool kconsole_check_poll(void) |
{ |
return check_poll(stdin); |
} |
/** Kernel console prompt. |
* |
* @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. |
* |
*/ |
void kconsole(void *prompt) |
void kconsole(char *prompt, char *msg, bool kcon) |
{ |
cmd_info_t *cmd_info; |
count_t len; |
char *cmdline; |
if (!stdin) { |
printf("%s: no stdin\n", __func__); |
LOG("No stdin for kernel console"); |
return; |
} |
if (msg) |
printf("%s", msg); |
if (kcon) |
_getc(stdin); |
else |
printf("Type \"exit\" to leave the console.\n"); |
while (true) { |
cmdline = clever_readline((char *) prompt, stdin); |
len = strlen(cmdline); |
if (!len) |
continue; |
if ((!kcon) && (len == 4) && (strncmp(cmdline, "exit", 4) == 0)) |
break; |
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); |
} |
} |
/** Kernel console managing thread. |
* |
*/ |
void kconsole_thread(void *data) |
{ |
kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true); |
} |
static int parse_int_arg(char *text, size_t len, unative_t *result) |
{ |
static char symname[MAX_SYMBOL_NAME]; |
uintptr_t symaddr; |
bool isaddr = false; |
bool isptr = false; |
int rc; |
static char symname[MAX_SYMBOL_NAME]; |
/* If we get a name, try to find it in symbol table */ |
if (text[0] == '&') { |
450,16 → 531,20 |
} |
if (text[0] < '0' || text[0] > '9') { |
strncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME)); |
symaddr = get_symbol_addr(symname); |
if (!symaddr) { |
rc = symtab_addr_lookup(symname, &symaddr); |
switch (rc) { |
case ENOENT: |
printf("Symbol %s not found.\n", symname); |
return -1; |
} |
if (symaddr == (uintptr_t) -1) { |
case EOVERFLOW: |
printf("Duplicate symbol %s.\n", symname); |
symtab_print_search(symname); |
return -1; |
default: |
printf("No symbol information available.\n"); |
return -1; |
} |
if (isaddr) |
*result = (unative_t)symaddr; |
else if (isptr) |
/branches/network/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; |
} |
/branches/network/kernel/generic/src/proc/task.c |
---|
52,6 → 52,7 |
#include <print.h> |
#include <errno.h> |
#include <func.h> |
#include <string.h> |
#include <syscall/copy.h> |
/** Spinlock protecting the tasks_tree AVL tree. */ |
130,7 → 131,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 → 149,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; |
155,7 → 159,18 |
ta->capabilities = 0; |
ta->cycles = 0; |
#ifdef CONFIG_UDEBUG |
/* Init debugging stuff */ |
udebug_task_init(&ta->udebug); |
/* Init kbox stuff */ |
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); |
for (i = 0; i < IPC_MAX_PHONES; i++) |
ipc_phone_init(&ta->phones[i]); |
235,6 → 250,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'; |
strncpy(TASK->name, namebuf, TASK_NAME_BUFLEN); |
return EOK; |
} |
/** Find task structure corresponding to task ID. |
* |
* The tasks_lock must be already held by the caller of this function and |
325,7 → 369,7 |
bool sleeping = false; |
thr = list_get_instance(cur, thread_t, th_link); |
spinlock_lock(&thr->lock); |
thr->interrupted = true; |
if (thr->state == Sleeping) |
353,13 → 397,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 |
384,16 → 428,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/network/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; |
136,7 → 138,7 |
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/network/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/network/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 |
180,6 → 180,10 |
return -1; |
} |
#ifdef CONFIG_UDEBUG |
mutex_initialize(&t->udebug.lock, MUTEX_PASSIVE); |
#endif |
return 0; |
} |
192,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 |
207,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 |
275,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. |
* |
312,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; |
347,6 → 352,11 |
avltree_node_initialize(&t->threads_tree_node); |
t->threads_tree_node.key = (uintptr_t) t; |
#ifdef CONFIG_UDEBUG |
/* Init debugging stuff */ |
udebug_thread_initialize(&t->udebug); |
#endif |
/* might depend on previous initialization */ |
thread_create_arch(t); |
409,12 → 419,17 |
ipl_t ipl; |
/* |
* Attach to the current task. |
* Attach to the specified task. |
*/ |
ipl = interrupts_disable(); |
spinlock_lock(&task->lock); |
atomic_inc(&task->refcount); |
atomic_inc(&task->lifecount); |
/* Must not count kbox thread into lifecount */ |
if (t->flags & THREAD_FLAG_USPACE) |
atomic_inc(&task->lifecount); |
list_append(&t->th_link, &task->th_head); |
spinlock_unlock(&task->lock); |
437,14 → 452,19 |
{ |
ipl_t ipl; |
if (atomic_predec(&TASK->lifecount) == 0) { |
/* |
* We are the last thread in the task that still has not exited. |
* With the exception of the moment the task was created, new |
* threads can only be created by threads of the same task. |
* We are safe to perform cleanup. |
*/ |
if (THREAD->flags & THREAD_FLAG_USPACE) { |
if (THREAD->flags & THREAD_FLAG_USPACE) { |
#ifdef CONFIG_UDEBUG |
/* Generate udebug THREAD_E event */ |
udebug_thread_e_event(); |
#endif |
if (atomic_predec(&TASK->lifecount) == 0) { |
/* |
* We are the last userspace thread in the task that |
* still has not exited. With the exception of the |
* moment the task was created, new userspace threads |
* can only be created by threads of the same task. |
* We are safe to perform cleanup. |
*/ |
ipc_cleanup(); |
futex_cleanup(); |
LOG("Cleanup of task %" PRIu64" completed.", TASK->taskid); |
689,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]; |
696,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(). |
738,7 → 763,18 |
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); |
return 0; |
/branches/network/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/network/kernel/generic/src/lib/string.c |
---|
0,0 → 1,170 |
/* |
* 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 Miscellaneous functions. |
*/ |
#include <string.h> |
#include <print.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <arch.h> |
#include <console/kconsole.h> |
/** 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'; |
} |
/** Find first occurence of character in string. |
* |
* @param s String to search. |
* @param i Character to look for. |
* |
* @return Pointer to character in @a s or NULL if not found. |
*/ |
extern char *strchr(const char *s, int i) |
{ |
while (*s != '\0') { |
if (*s == i) |
return (char *) s; |
++s; |
} |
return NULL; |
} |
/** @} |
*/ |
/branches/network/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 |
34,12 → 35,10 |
* @file |
* @brief Memory string operations. |
* |
* This file provides architecture independent functions |
* to manipulate blocks of memory. These functions |
* are optimized as much as generic functions of |
* this type can be. However, architectures are |
* free to provide even more optimized versions of these |
* functions. |
* This file provides architecture independent functions to manipulate blocks of |
* memory. These functions are optimized as much as generic functions of this |
* type can be. However, architectures are free to provide even more optimized |
* versions of these functions. |
*/ |
#include <memstr.h> |
46,45 → 45,91 |
#include <arch/types.h> |
#include <align.h> |
/** Copy block of memory |
/** Copy block of memory. |
* |
* Copy cnt bytes from src address to dst address. |
* The copying is done word-by-word and then byte-by-byte. |
* The source and destination memory areas cannot overlap. |
* Copy cnt bytes from src address to dst address. The copying is done |
* word-by-word and then byte-by-byte. The source and destination memory areas |
* cannot overlap. |
* |
* @param src Origin address to copy from. |
* @param dst Origin address to copy to. |
* @param cnt Number of bytes to copy. |
* @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 *_memcpy(void * dst, const void *src, size_t cnt) |
void *_memcpy(void *dst, const void *src, size_t cnt) |
{ |
unsigned int i, j; |
if (ALIGN_UP((uintptr_t) src, sizeof(unative_t)) != (uintptr_t) src || |
ALIGN_UP((uintptr_t) dst, sizeof(unative_t)) != (uintptr_t) dst) { |
ALIGN_UP((uintptr_t) dst, sizeof(unative_t)) != (uintptr_t) dst) { |
for (i = 0; i < cnt; i++) |
((uint8_t *) dst)[i] = ((uint8_t *) src)[i]; |
} else { |
for (i = 0; i < cnt / sizeof(unative_t); i++) |
((unative_t *) dst)[i] = ((unative_t *) src)[i]; |
for (j = 0; j < cnt % sizeof(unative_t); j++) |
((uint8_t *)(((unative_t *) dst) + i))[j] = ((uint8_t *)(((unative_t *) src) + i))[j]; |
((uint8_t *)(((unative_t *) dst) + i))[j] = |
((uint8_t *)(((unative_t *) src) + i))[j]; |
} |
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 byte-by-byte. |
* Fill cnt bytes at dst address with the value x. The filling is done |
* byte-by-byte. |
* |
* @param dst Origin address to fill. |
* @param cnt Number of bytes to fill. |
* @param x Value to fill. |
* @param dst Destination address to fill. |
* @param cnt Number of bytes to fill. |
* @param x Value to fill. |
* |
*/ |
void _memsetb(void *dst, size_t cnt, uint8_t x) |
96,14 → 141,14 |
p[i] = x; |
} |
/** Fill block of memory |
/** Fill block of memory. |
* |
* Fill cnt words at dst address with the value x. |
* The filling is done word-by-word. |
* Fill cnt words at dst address with the value x. The filling is done |
* word-by-word. |
* |
* @param dst Origin address to fill. |
* @param cnt Number of words to fill. |
* @param x Value to fill. |
* @param dst Destination address to fill. |
* @param cnt Number of words to fill. |
* @param x Value to fill. |
* |
*/ |
void _memsetw(void *dst, size_t cnt, uint16_t x) |
115,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 Origin string to copy from. |
* @param dst Origin string to copy to. |
* |
*/ |
char *strcpy(char *dest, const char *src) |
{ |
char *orig = dest; |
while ((*(dest++) = *(src++))) |
; |
return orig; |
} |
/** @} |
*/ |
/branches/network/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/network/kernel/generic/src/adt/btree.c |
---|
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); |
} |
} |
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); |
} |
} |
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. |
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. |
693,7 → 693,7 |
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. |
/branches/network/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/network/kernel/generic/src/adt/hash_table.c |
---|
61,7 → 61,7 |
h->entry = (link_t *) malloc(m * sizeof(link_t), 0); |
if (!h->entry) { |
panic("cannot allocate memory for hash table\n"); |
panic("Cannot allocate memory for hash table."); |
} |
memsetb(h->entry, m * sizeof(link_t), 0); |
/branches/network/kernel/generic/src/mm/slab.c |
---|
173,7 → 173,7 |
slab_t *slab; |
size_t fsize; |
unsigned int i; |
unsigned int zone = 0; |
count_t zone = 0; |
data = frame_alloc_generic(cache->order, FRAME_KA | flags, &zone); |
if (!data) { |
/branches/network/kernel/generic/src/mm/tlb.c |
---|
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/network/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; |
} |
/branches/network/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; |
} |
385,7 → 389,7 |
if (pages < area->pages) { |
bool cond; |
uintptr_t start_free = area->base + pages*PAGE_SIZE; |
uintptr_t start_free = area->base + pages * PAGE_SIZE; |
/* |
* Shrinking the area. |
395,7 → 399,7 |
/* |
* Start TLB shootdown sequence. |
*/ |
tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base + |
tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base + |
pages * PAGE_SIZE, area->pages - pages); |
/* |
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++) { |
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) |
{ |
785,7 → 790,7 |
uintptr_t *old_frame; |
index_t frame_idx; |
count_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); |
870,6 → 875,7 |
*/ |
tlb_invalidate_pages(as->asid, area->base, area->pages); |
/* |
* Invalidate potential software translation caches (e.g. TSB on |
* sparc64). |
1660,7 → 1666,7 |
} |
panic("Inconsistency detected while adding %" PRIc " pages of used " |
"space at %p.\n", count, page); |
"space at %p.", count, page); |
} |
/** Mark portion of address space area as unused. |
1839,7 → 1845,7 |
error: |
panic("Inconsistency detected while removing %" PRIc " pages of used " |
"space from %p.\n", count, page); |
"space from %p.", count, page); |
} |
/** Remove reference to address space area share info. |
/branches/network/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/network/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/network/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,50 → 59,16 |
#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. */ |
count_t mem_avail_req = 0; /**< Number of frames requested. */ |
count_t mem_avail_gen = 0; /**< Generation counter. */ |
/********************/ |
/* Helper functions */ |
128,13 → 84,12 |
return (index_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, index_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 index_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 count_t zones_insert_zone(pfn_t base, count_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 (count_t) -1; |
} |
count_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 (count_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]; |
count_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 count_t total_frames_free(void) |
{ |
unsigned int i; |
unsigned int hint = pzone ? *pzone : 0; |
zone_t *z; |
count_t total = 0; |
count_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. |
* |
*/ |
count_t find_zone(pfn_t frame, count_t count, count_t hint) |
{ |
if (hint >= zones.count) |
hint = 0; |
i = hint; |
count_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 (count_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 count_t find_free_zone(uint8_t order, zone_flags_t flags, count_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; |
count_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 (count_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); |
index_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); |
index_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) |
{ |
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); |
547,567 → 476,633 |
/** Mark frame in zone unavailable to allocation. */ |
static void zone_mark_unavailable(zone_t *zone, index_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(count_t z1, count_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 */ |
count_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(count_t znum, pfn_t pfn, count_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) |
count_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); |
count_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(count_t znum, pfn_t frame_idx, count_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; |
uint8_t order = zones.info[znum].frames[frame_idx].buddy_order; |
ASSERT((count_t) (1 << order) >= count); |
/* Reduce all blocks to order 0 */ |
count_t i; |
for (i = 0; i < (count_t) (1 << order); i++) { |
frame = &zone->frames[i + frame_idx]; |
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 < (count_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(count_t z1, count_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 */ |
count_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; |
count_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, count_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)); |
count_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) |
{ |
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) |
count_t zone_create(pfn_t start, count_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 |
*/ |
count_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; |
count_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."); |
count_t znum = zones_insert_zone(start, count); |
if (znum == (count_t) -1) { |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return (count_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)) { |
count_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 */ |
count_t znum = zones_insert_zone(start, count); |
if (znum == (count_t) -1) { |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return (count_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, count_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); |
count_t znum = find_zone(pfn, 1, hint); |
ASSERT(znum != (count_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, count_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); |
count_t znum = find_zone(pfn, 1, hint); |
ASSERT(znum != (count_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, count_t *pzone) |
{ |
count_t size = ((count_t) 1) << order; |
ipl_t ipl; |
int freed; |
pfn_t v; |
zone_t *zone; |
unsigned long gen = 0; |
count_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); |
count_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 == (count_t) -1) && (!(flags & FRAME_NO_RECLAIM))) { |
count_t freed = slab_reclaim(0); |
if (freed > 0) |
znum = find_free_zone(order, |
FRAME_TO_ZONE_FLAGS(flags), hint); |
if (znum == (count_t) -1) { |
freed = slab_reclaim(SLAB_RECLAIM_ALL); |
if (freed) |
zone = find_free_zone_and_lock(order, flags, |
pzone); |
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 == (count_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); |
count_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 %" PRIc " frames, " |
"%" PRIc " 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; |
count_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); |
count_t znum = find_zone(pfn, 1, NULL); |
zone_frame_free(zone, pfn - zone->base); |
ASSERT(znum != (count_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,26 → 1110,24 |
* 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); |
count_t znum = find_zone(pfn, 1, NULL); |
frame = &zone->frames[pfn - zone->base]; |
frame->refcount++; |
ASSERT(znum != (count_t) -1); |
spinlock_unlock(&zone->lock); |
zones.info[znum].frames[pfn - zones.info[znum].base].refcount++; |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
} |
1141,18 → 1134,21 |
/** Mark given range unavailable in frame zones. */ |
void frame_mark_unavailable(pfn_t start, count_t count) |
{ |
unsigned int i; |
zone_t *zone; |
unsigned int prefzone = 0; |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
count_t i; |
for (i = 0; i < count; i++) { |
zone = find_zone_and_lock(start + i, &prefzone); |
if (!zone) /* PFN not found */ |
count_t znum = find_zone(start + i, 1, 0); |
if (znum == (count_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 → 1160,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) { |
1178,35 → 1175,28 |
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; |
count_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 → 1207,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 → 1227,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(); |
count_t i; |
for (i = 0;; i++) { |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
if (i >= zones.count) { |
1255,56 → 1238,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); |
count_t count = zones.info[i].count; |
zone_flags_t flags = zones.info[i].flags; |
count_t free_count = zones.info[i].free_count; |
count_t busy_count = zones.info[i].busy_count; |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
bool available = zone_flags_available(flags); |
printf("%-2" PRIc, 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" PRIc " %c%c%c ", count, |
available ? 'A' : ' ', |
(flags & ZONE_RESERVED) ? 'R' : ' ', |
(flags & ZONE_FIRMWARE) ? 'F' : ' '); |
if (available) |
printf("%12" PRIc " %12" PRIc, |
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(count_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); |
count_t znum = (count_t) -1; |
count_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 == (count_t) -1) { |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
printf("Zone not found.\n"); |
1311,24 → 1299,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; |
count_t count = zones.info[i].count; |
count_t free_count = zones.info[i].free_count; |
count_t busy_count = zones.info[i].busy_count; |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
bool available = zone_flags_available(flags); |
printf("Zone number: %" PRIc "\n", znum); |
printf("Zone base address: %p\n", base); |
printf("Zone size: %" PRIc " frames (%" PRIs " KiB)\n", count, |
printf("Zone size: %" PRIc " 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: %" 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))); |
} |
} |
/** @} |
*/ |
/branches/network/kernel/generic/src/mm/backend_elf.c |
---|
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; |
} |
/branches/network/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> |
42,76 → 42,50 |
#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 <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) |
{ |
unative_t rc; |
if (id < SYSCALL_END) |
#ifdef CONFIG_UDEBUG |
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 { |
} else { |
printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id); |
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); |
/* |
* Stopping point needed for tasks that only invoke non-blocking |
* system calls. |
*/ |
udebug_stoppable_begin(); |
udebug_stoppable_end(); |
#endif |
return rc; |
} |
125,6 → 99,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. */ |
146,6 → 121,7 |
(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, |
156,6 → 132,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, |
165,7 → 142,10 |
(syshandler_t) sys_sysinfo_value, |
/* Debug calls */ |
(syshandler_t) sys_debug_enable_console |
(syshandler_t) sys_debug_enable_console, |
(syshandler_t) sys_debug_disable_console, |
(syshandler_t) sys_ipc_connect_kbox |
}; |
/** @} |
/branches/network/kernel/generic/src/ipc/kbox.c |
---|
0,0 → 1,284 |
/* |
* Copyright (c) 2008 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 genericipc |
* @{ |
*/ |
/** @file |
*/ |
#include <synch/synch.h> |
#include <synch/spinlock.h> |
#include <synch/mutex.h> |
#include <ipc/ipc.h> |
#include <ipc/ipcrsc.h> |
#include <arch.h> |
#include <errno.h> |
#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); |
have_kb_thread = (TASK->kb.thread != NULL); |
/* |
* From now on nobody will try to connect phones or attach |
* kbox threads |
*/ |
/* |
* Disconnect all phones connected to our kbox. Passing true for |
* notify_box causes a HANGUP message to be inserted for each |
* disconnected phone. This ensures the kbox thread is going to |
* wake up and terminate. |
*/ |
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; |
} |
/* 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; |
LOG("kbox_proc_phone_hungup()\n"); |
/* 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"); |
} |
LOG("kbox: continue with hangup message\n"); |
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\n"); |
*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; |
bool done; |
(void)arg; |
LOG("kbox_thread_proc()\n"); |
done = false; |
while (!done) { |
call = ipc_wait_for_call(&TASK->kb.box, SYNCH_NO_TIMEOUT, |
SYNCH_FLAGS_NONE); |
if (call == NULL) |
continue; /* Try again. */ |
switch (IPC_GET_METHOD(call->data)) { |
case IPC_M_DEBUG_ALL: |
/* Handle debug call. */ |
udebug_call_receive(call); |
break; |
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; |
default: |
/* Ignore */ |
break; |
} |
} |
LOG("kbox: finished\n"); |
} |
/** |
* 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. |
* |
* @return Phone id on success, or negative error code. |
*/ |
int ipc_connect_kbox(task_id_t taskid) |
{ |
int newphid; |
task_t *ta; |
thread_t *kb_thread; |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&tasks_lock); |
ta = task_find_by_id(taskid); |
if (ta == NULL) { |
spinlock_unlock(&tasks_lock); |
interrupts_restore(ipl); |
return ENOENT; |
} |
atomic_inc(&ta->refcount); |
spinlock_unlock(&tasks_lock); |
interrupts_restore(ipl); |
mutex_lock(&ta->kb.cleanup_lock); |
if (atomic_predec(&ta->refcount) == 0) { |
mutex_unlock(&ta->kb.cleanup_lock); |
task_destroy(ta); |
return ENOENT; |
} |
if (ta->kb.finished != false) { |
mutex_unlock(&ta->kb.cleanup_lock); |
return EINVAL; |
} |
newphid = phone_alloc(); |
if (newphid < 0) { |
mutex_unlock(&ta->kb.cleanup_lock); |
return ELIMIT; |
} |
/* Connect the newly allocated phone to the kbox */ |
ipc_phone_connect(&TASK->phones[newphid], &ta->kb.box); |
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); |
if (!kb_thread) { |
mutex_unlock(&ta->kb.cleanup_lock); |
return ENOMEM; |
} |
ta->kb.thread = kb_thread; |
thread_ready(kb_thread); |
mutex_unlock(&ta->kb.cleanup_lock); |
return newphid; |
} |
/** @} |
*/ |
/branches/network/kernel/generic/src/ipc/sysipc.c |
---|
42,8 → 42,9 |
#include <ipc/sysipc.h> |
#include <ipc/irq.h> |
#include <ipc/ipcrsc.h> |
#include <ipc/kbox.h> |
#include <udebug/udebug_ipc.h> |
#include <arch/interrupt.h> |
#include <print.h> |
#include <syscall/copy.h> |
#include <security/cap.h> |
#include <mm/as.h> |
295,10 → 296,11 |
/** Called before the request is sent. |
* |
* @param call Call structure with the request. |
* @param phone Phone that the call will be sent through. |
* |
* @return Return 0 on success, ELIMIT or EPERM on error. |
*/ |
static int request_preprocess(call_t *call) |
static int request_preprocess(call_t *call, phone_t *phone) |
{ |
int newphid; |
size_t size; |
340,6 → 342,10 |
return rc; |
} |
break; |
#ifdef CONFIG_UDEBUG |
case IPC_M_DEBUG_ALL: |
return udebug_request_preprocess(call, phone); |
#endif |
default: |
break; |
} |
369,6 → 375,7 |
if (call->buffer) { |
/* This must be an affirmative answer to IPC_M_DATA_READ. */ |
/* or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ... */ |
uintptr_t dst = IPC_GET_ARG1(call->data); |
size_t size = IPC_GET_ARG2(call->data); |
int rc = copy_to_uspace((void *) dst, call->buffer, size); |
399,7 → 406,13 |
return -1; |
} |
IPC_SET_ARG5(call->data, phoneid); |
} |
} |
switch (IPC_GET_METHOD(call->data)) { |
case IPC_M_DEBUG_ALL: |
return -1; |
default: |
break; |
} |
return 0; |
} |
441,11 → 454,18 |
IPC_SET_ARG4(call.data, 0); |
IPC_SET_ARG5(call.data, 0); |
if (!(res = request_preprocess(&call))) { |
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); |
} |
481,8 → 501,14 |
GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
if (!(res = request_preprocess(&call))) { |
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); |
550,7 → 576,7 |
*/ |
IPC_SET_ARG5(call->data, 0); |
if (!(res = request_preprocess(call))) |
if (!(res = request_preprocess(call, phone))) |
ipc_call(phone, call); |
else |
ipc_backsend_err(phone, call, res); |
584,7 → 610,7 |
ipc_call_free(call); |
return (unative_t) rc; |
} |
if (!(res = request_preprocess(call))) |
if (!(res = request_preprocess(call, phone))) |
ipc_call(phone, call); |
else |
ipc_backsend_err(phone, call, res); |
592,7 → 618,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. |
599,23 → 626,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; |
623,7 → 648,7 |
call = get_call(callid); |
if (!call) |
return ENOENT; |
call->flags |= IPC_CALL_FORWARDED; |
GET_CHECK_PHONE(phone, phoneid, { |
640,8 → 665,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))) { |
652,10 → 677,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); |
} |
} |
} |
662,6 → 699,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 |
785,9 → 880,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; |
809,11 → 912,16 |
ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC)); |
atomic_dec(&TASK->active_calls); |
if (call->flags & IPC_CALL_DISCARD_ANSWER) { |
ipc_call_free(call); |
goto restart; |
} else { |
/* |
* Decrement the counter of active calls only if the |
* call is not an answer to IPC_M_PHONE_HUNGUP, |
* which doesn't contribute to the counter. |
*/ |
atomic_dec(&TASK->active_calls); |
} |
STRUCT_TO_USPACE(&calldata->args, &call->data.args); |
828,6 → 936,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; |
868,5 → 991,30 |
return 0; |
} |
#include <console/console.h> |
/** |
* Syscall connect to a task by id. |
* |
* @return Phone id on success, or negative error code. |
*/ |
unative_t sys_ipc_connect_kbox(sysarg64_t *uspace_taskid_arg) |
{ |
#ifdef CONFIG_UDEBUG |
sysarg64_t taskid_arg; |
int rc; |
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t)); |
if (rc != 0) |
return (unative_t) rc; |
LOG("sys_ipc_connect_kbox(%" PRIu64 ")\n", taskid_arg.value); |
return ipc_connect_kbox(taskid_arg.value); |
#else |
return (unative_t) ENOTSUP; |
#endif |
} |
/** @} |
*/ |
/branches/network/kernel/generic/src/ipc/ipc.c |
---|
43,6 → 43,7 |
#include <synch/waitq.h> |
#include <synch/synch.h> |
#include <ipc/ipc.h> |
#include <ipc/kbox.h> |
#include <errno.h> |
#include <mm/slab.h> |
#include <arch.h> |
51,6 → 52,7 |
#include <debug.h> |
#include <print.h> |
#include <console/console.h> |
#include <proc/thread.h> |
#include <arch/interrupt.h> |
#include <ipc/irq.h> |
201,9 → 203,9 |
call->flags |= IPC_CALL_ANSWERED; |
if (call->flags & IPC_CALL_FORWARDED) { |
if (call->data.caller_phone) { |
if (call->caller_phone) { |
/* Demasquerade the caller phone. */ |
call->data.phone = call->data.caller_phone; |
call->data.phone = call->caller_phone; |
} |
} |
360,8 → 362,8 |
spinlock_unlock(&oldbox->lock); |
if (mode & IPC_FF_ROUTE_FROM_ME) { |
if (!call->data.caller_phone) |
call->data.caller_phone = call->data.phone; |
if (!call->caller_phone) |
call->caller_phone = call->data.phone; |
call->data.phone = newphone; |
} |
427,7 → 429,7 |
* |
* @param lst Head of the list to be cleaned up. |
*/ |
static void ipc_cleanup_call_list(link_t *lst) |
void ipc_cleanup_call_list(link_t *lst) |
{ |
call_t *call; |
442,33 → 444,31 |
} |
} |
/** Cleans up all IPC communication of the current task. |
/** Disconnects all phones connected to an answerbox. |
* |
* Note: ipc_hangup sets returning answerbox to TASK->answerbox, you |
* have to change it as well if you want to cleanup other tasks than TASK. |
* @param box Answerbox to disconnect phones from. |
* @param notify_box If true, the answerbox will get a hangup message for |
* each disconnected phone. |
*/ |
void ipc_cleanup(void) |
void ipc_answerbox_slam_phones(answerbox_t *box, bool notify_box) |
{ |
int i; |
call_t *call; |
phone_t *phone; |
DEADLOCK_PROBE_INIT(p_phonelck); |
ipl_t ipl; |
call_t *call; |
/* Disconnect all our phones ('ipc_phone_hangup') */ |
for (i = 0; i < IPC_MAX_PHONES; i++) |
ipc_phone_hangup(&TASK->phones[i]); |
call = notify_box ? ipc_call_alloc(0) : NULL; |
/* Disconnect all connected irqs */ |
ipc_irq_cleanup(&TASK->answerbox); |
/* Disconnect all phones connected to our answerbox */ |
restart_phones: |
spinlock_lock(&TASK->answerbox.lock); |
while (!list_empty(&TASK->answerbox.connected_phones)) { |
phone = list_get_instance(TASK->answerbox.connected_phones.next, |
ipl = interrupts_disable(); |
spinlock_lock(&box->lock); |
while (!list_empty(&box->connected_phones)) { |
phone = list_get_instance(box->connected_phones.next, |
phone_t, link); |
if (SYNCH_FAILED(mutex_trylock(&phone->lock))) { |
spinlock_unlock(&TASK->answerbox.lock); |
spinlock_unlock(&box->lock); |
interrupts_restore(ipl); |
DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD); |
goto restart_phones; |
} |
475,13 → 475,70 |
/* Disconnect phone */ |
ASSERT(phone->state == IPC_PHONE_CONNECTED); |
list_remove(&phone->link); |
phone->state = IPC_PHONE_SLAMMED; |
list_remove(&phone->link); |
if (notify_box) { |
mutex_unlock(&phone->lock); |
spinlock_unlock(&box->lock); |
interrupts_restore(ipl); |
/* |
* Send one message to the answerbox for each |
* phone. Used to make sure the kbox thread |
* wakes up after the last phone has been |
* disconnected. |
*/ |
IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP); |
call->flags |= IPC_CALL_DISCARD_ANSWER; |
_ipc_call(phone, box, call); |
/* Allocate another call in advance */ |
call = ipc_call_alloc(0); |
/* Must start again */ |
goto restart_phones; |
} |
mutex_unlock(&phone->lock); |
} |
spinlock_unlock(&box->lock); |
interrupts_restore(ipl); |
/* Free unused call */ |
if (call) |
ipc_call_free(call); |
} |
/** Cleans up all IPC communication of the current task. |
* |
* Note: ipc_hangup sets returning answerbox to TASK->answerbox, you |
* have to change it as well if you want to cleanup other tasks than TASK. |
*/ |
void ipc_cleanup(void) |
{ |
int i; |
call_t *call; |
/* Disconnect all our phones ('ipc_phone_hangup') */ |
for (i = 0; i < IPC_MAX_PHONES; i++) |
ipc_phone_hangup(&TASK->phones[i]); |
/* Disconnect all connected irqs */ |
ipc_irq_cleanup(&TASK->answerbox); |
/* Disconnect all phones connected to our regular answerbox */ |
ipc_answerbox_slam_phones(&TASK->answerbox, false); |
#ifdef CONFIG_UDEBUG |
/* Clean up kbox thread and communications */ |
ipc_kbox_cleanup(); |
#endif |
/* Answer all messages in 'calls' and 'dispatched_calls' queues */ |
spinlock_lock(&TASK->answerbox.lock); |
ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls); |
ipc_cleanup_call_list(&TASK->answerbox.calls); |
spinlock_unlock(&TASK->answerbox.lock); |
517,7 → 574,13 |
(call->flags & IPC_CALL_NOTIF)); |
ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC)); |
atomic_dec(&TASK->active_calls); |
/* |
* Record the receipt of this call in the current task's counter |
* of active calls. IPC_M_PHONE_HUNGUP calls do not contribute |
* to this counter so do not record answers to them either. |
*/ |
if (!(call->flags & IPC_CALL_DISCARD_ANSWER)) |
atomic_dec(&TASK->active_calls); |
ipc_call_free(call); |
} |
} |
592,8 → 655,9 |
tmp = tmp->next) { |
call = list_get_instance(tmp, call_t, link); |
printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun |
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun |
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, call->sender->taskid, |
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun |
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, |
call->sender->taskid, |
IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data), |
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), |
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data), |
606,8 → 670,9 |
tmp = tmp->next) { |
call = list_get_instance(tmp, call_t, link); |
printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun |
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun |
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, call->sender->taskid, |
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun |
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, |
call->sender->taskid, |
IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data), |
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), |
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data), |
615,11 → 680,12 |
} |
/* Print answerbox - calls */ |
printf("ABOX - ANSWERS:\n"); |
for (tmp = task->answerbox.answers.next; tmp != &task->answerbox.answers; |
for (tmp = task->answerbox.answers.next; |
tmp != &task->answerbox.answers; |
tmp = tmp->next) { |
call = list_get_instance(tmp, call_t, link); |
printf("Callid:%p M:%" PRIun " A1:%" PRIun " A2:%" PRIun |
" A3:%" PRIun " A4:%" PRIun " A5:%" PRIun " Flags:%x\n", |
" A3:%" PRIun " A4:%" PRIun " A5:%" PRIun " Flags:%x\n", |
call, IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data), |
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), |
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data), |
/branches/network/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,38 → 126,6 |
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. |
224,6 → 142,10 |
ipl_t ipl; |
irq_code_t *code; |
irq_t *irq; |
unative_t key[] = { |
(unative_t) inr, |
(unative_t) devno |
}; |
if (ucode) { |
code = code_from_uspace(ucode); |
233,21 → 155,15 |
code = NULL; |
} |
ipl = interrupts_disable(); |
irq = irq_find_and_lock(inr, devno); |
if (!irq) { |
interrupts_restore(ipl); |
code_free(code); |
return ENOENT; |
} |
if (irq->notif_cfg.answerbox) { |
spinlock_unlock(&irq->lock); |
interrupts_restore(ipl); |
code_free(code); |
return EEXISTS; |
} |
/* |
* 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; |
254,14 → 170,140 |
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(); |
spinlock_lock(&irq_uspace_hash_table_lock); |
spinlock_lock(&irq->lock); |
spinlock_lock(&box->irq_lock); |
if (hash_table_find(&irq_uspace_hash_table, key)) { |
code_free(code); |
spinlock_unlock(&box->irq_lock); |
spinlock_unlock(&irq->lock); |
spinlock_unlock(&irq_uspace_hash_table_lock); |
free(irq); |
interrupts_restore(ipl); |
return EEXISTS; |
} |
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); |
spinlock_lock(&irq->lock); |
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); |
/* 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(&irq->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); |
/* Remove from the hash table. */ |
hash_table_remove(&irq_uspace_hash_table, key, 2); |
/* Free up the pseudo code and associated structures. */ |
code_free(irq->notif_cfg.code); |
spinlock_unlock(&irq->lock); |
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 → 322,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/network/kernel/generic/src/udebug/udebug.c |
---|
0,0 → 1,504 |
/* |
* Copyright (c) 2008 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 generic |
* @{ |
*/ |
/** |
* @file |
* @brief Udebug hooks and data structure management. |
* |
* Udebug is an interface that makes userspace debuggers possible. |
*/ |
#include <synch/waitq.h> |
#include <debug.h> |
#include <udebug/udebug.h> |
#include <errno.h> |
#include <print.h> |
#include <arch.h> |
/** Initialize udebug part of task structure. |
* |
* Called as part of task structure initialization. |
* @param ut Pointer to the structure to initialize. |
*/ |
void udebug_task_init(udebug_task_t *ut) |
{ |
mutex_initialize(&ut->lock, MUTEX_PASSIVE); |
ut->dt_state = UDEBUG_TS_INACTIVE; |
ut->begin_call = NULL; |
ut->not_stoppable_count = 0; |
ut->evmask = 0; |
} |
/** Initialize udebug part of thread structure. |
* |
* Called as part of thread structure initialization. |
* @param ut Pointer to the structure to initialize. |
*/ |
void udebug_thread_initialize(udebug_thread_t *ut) |
{ |
mutex_initialize(&ut->lock, MUTEX_PASSIVE); |
waitq_initialize(&ut->go_wq); |
ut->go_call = NULL; |
ut->uspace_state = NULL; |
ut->go = false; |
ut->stoppable = true; |
ut->active = false; |
ut->cur_event = 0; /* none */ |
} |
/** Wait for a GO message. |
* |
* When a debugging event occurs in a thread or the thread is stopped, |
* this function is called to block the thread until a GO message |
* is received. |
* |
* @param wq The wait queue used by the thread to wait for GO messages. |
*/ |
static void udebug_wait_for_go(waitq_t *wq) |
{ |
int rc; |
ipl_t ipl; |
ipl = waitq_sleep_prepare(wq); |
wq->missed_wakeups = 0; /* Enforce blocking. */ |
rc = waitq_sleep_timeout_unsafe(wq, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE); |
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.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, |
* if a STOP operation is issued, the thread is guaranteed not to execute |
* any userspace instructions until the thread is resumed. |
* |
* Having stoppable sections is better than having stopping points, since |
* a thread can be stopped even when it is blocked indefinitely in a system |
* call (whereas it would not reach any stopping point). |
*/ |
void udebug_stoppable_begin(void) |
{ |
int nsc; |
call_t *db_call, *go_call; |
ASSERT(THREAD); |
ASSERT(TASK); |
/* Early check for undebugged tasks */ |
if (!udebug_thread_precheck()) { |
return; |
} |
mutex_lock(&TASK->udebug.lock); |
nsc = --TASK->udebug.not_stoppable_count; |
/* Lock order OK, THREAD->udebug.lock is after TASK->udebug.lock */ |
mutex_lock(&THREAD->udebug.lock); |
ASSERT(THREAD->udebug.stoppable == false); |
THREAD->udebug.stoppable = true; |
if (TASK->udebug.dt_state == UDEBUG_TS_BEGINNING && nsc == 0) { |
/* |
* This was the last non-stoppable thread. Reply to |
* DEBUG_BEGIN call. |
*/ |
db_call = TASK->udebug.begin_call; |
ASSERT(db_call); |
TASK->udebug.dt_state = UDEBUG_TS_ACTIVE; |
TASK->udebug.begin_call = NULL; |
IPC_SET_RETVAL(db_call->data, 0); |
ipc_answer(&TASK->answerbox, db_call); |
} else if (TASK->udebug.dt_state == UDEBUG_TS_ACTIVE) { |
/* |
* Active debugging session |
*/ |
if (THREAD->udebug.active == true && |
THREAD->udebug.go == false) { |
/* |
* Thread was requested to stop - answer go call |
*/ |
/* Make sure nobody takes this call away from us */ |
go_call = THREAD->udebug.go_call; |
THREAD->udebug.go_call = NULL; |
ASSERT(go_call); |
IPC_SET_RETVAL(go_call->data, 0); |
IPC_SET_ARG1(go_call->data, UDEBUG_EVENT_STOP); |
THREAD->udebug.cur_event = UDEBUG_EVENT_STOP; |
ipc_answer(&TASK->answerbox, go_call); |
} |
} |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
} |
/** End of a stoppable section. |
* |
* This is the point where the thread will block if it is stopped. |
* (As, by definition, a stopped thread must not leave its stoppable section). |
*/ |
void udebug_stoppable_end(void) |
{ |
/* Early check for undebugged tasks */ |
if (!udebug_thread_precheck()) { |
return; |
} |
restart: |
mutex_lock(&TASK->udebug.lock); |
mutex_lock(&THREAD->udebug.lock); |
if (THREAD->udebug.active && THREAD->udebug.go == false) { |
TASK->udebug.begin_call = NULL; |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
udebug_wait_for_go(&THREAD->udebug.go_wq); |
goto restart; |
/* Must try again - have to lose stoppability atomically. */ |
} else { |
++TASK->udebug.not_stoppable_count; |
ASSERT(THREAD->udebug.stoppable == true); |
THREAD->udebug.stoppable = false; |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
} |
} |
/** Upon being scheduled to run, check if the current thread should stop. |
* |
* This function is called from clock(). |
*/ |
void udebug_before_thread_runs(void) |
{ |
/* Check if we're supposed to stop */ |
udebug_stoppable_begin(); |
udebug_stoppable_end(); |
} |
/** Syscall event hook. |
* |
* Must be called before and after servicing a system call. This generates |
* a SYSCALL_B or SYSCALL_E event, depending on the value of @a end_variant. |
*/ |
void udebug_syscall_event(unative_t a1, unative_t a2, unative_t a3, |
unative_t a4, unative_t a5, unative_t a6, unative_t id, unative_t rc, |
bool end_variant) |
{ |
call_t *call; |
udebug_event_t etype; |
etype = end_variant ? UDEBUG_EVENT_SYSCALL_E : UDEBUG_EVENT_SYSCALL_B; |
/* Early check for undebugged tasks */ |
if (!udebug_thread_precheck()) { |
return; |
} |
mutex_lock(&TASK->udebug.lock); |
mutex_lock(&THREAD->udebug.lock); |
/* 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); |
return; |
} |
//printf("udebug_syscall_event\n"); |
call = THREAD->udebug.go_call; |
THREAD->udebug.go_call = NULL; |
IPC_SET_RETVAL(call->data, 0); |
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; |
THREAD->udebug.syscall_args[2] = a3; |
THREAD->udebug.syscall_args[3] = a4; |
THREAD->udebug.syscall_args[4] = a5; |
THREAD->udebug.syscall_args[5] = a6; |
/* |
* 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.go = false; |
THREAD->udebug.cur_event = etype; |
ipc_answer(&TASK->answerbox, call); |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
udebug_wait_for_go(&THREAD->udebug.go_wq); |
} |
/** 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. 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_attach(struct thread *t, struct task *ta) |
{ |
call_t *call; |
mutex_lock(&TASK->udebug.lock); |
mutex_lock(&THREAD->udebug.lock); |
thread_attach(t, ta); |
LOG("udebug_thread_b_event\n"); |
LOG("- check state\n"); |
/* Must only generate events when in debugging session */ |
if (THREAD->udebug.active != true) { |
LOG("- udebug.active: %s, udebug.go: %s\n", |
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"); |
call = THREAD->udebug.go_call; |
THREAD->udebug.go_call = NULL; |
IPC_SET_RETVAL(call->data, 0); |
IPC_SET_ARG1(call->data, UDEBUG_EVENT_THREAD_B); |
IPC_SET_ARG2(call->data, (unative_t)t); |
/* |
* 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.go = false; |
THREAD->udebug.cur_event = UDEBUG_EVENT_THREAD_B; |
ipc_answer(&TASK->answerbox, call); |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
LOG("- sleep\n"); |
udebug_wait_for_go(&THREAD->udebug.go_wq); |
} |
/** Thread-termination event hook. |
* |
* Must be called when the current thread is terminating. |
* Generates a THREAD_E event. |
*/ |
void udebug_thread_e_event(void) |
{ |
call_t *call; |
mutex_lock(&TASK->udebug.lock); |
mutex_lock(&THREAD->udebug.lock); |
LOG("udebug_thread_e_event\n"); |
LOG("- check state\n"); |
/* Must only generate events when in debugging session. */ |
if (THREAD->udebug.active != true) { |
/* printf("- udebug.active: %s, udebug.go: %s\n", |
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"); |
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.active = false; |
THREAD->udebug.cur_event = 0; /* none */ |
THREAD->udebug.go = false; /* set to initial value */ |
ipc_answer(&TASK->answerbox, call); |
mutex_unlock(&THREAD->udebug.lock); |
mutex_unlock(&TASK->udebug.lock); |
/* |
* This event does not sleep - debugging has finished |
* in this thread. |
*/ |
} |
/** |
* Terminate task debugging session. |
* |
* Gracefully terminates the debugging session for a task. If the debugger |
* is still waiting for events on some threads, it will receive a |
* FINISHED event for each of them. |
* |
* @param ta Task structure. ta->udebug.lock must be already locked. |
* @return Zero on success or negative error code. |
*/ |
int udebug_task_cleanup(struct task *ta) |
{ |
thread_t *t; |
link_t *cur; |
int flags; |
ipl_t ipl; |
LOG("udebug_task_cleanup()\n"); |
LOG("task %" PRIu64 "\n", ta->taskid); |
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; |
} |
/* 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); |
mutex_lock(&t->udebug.lock); |
ipl = interrupts_disable(); |
spinlock_lock(&t->lock); |
flags = t->flags; |
spinlock_unlock(&t->lock); |
interrupts_restore(ipl); |
/* Only process userspace threads. */ |
if ((flags & THREAD_FLAG_USPACE) != 0) { |
/* Prevent any further debug activity in thread. */ |
t->udebug.active = false; |
t->udebug.cur_event = 0; /* none */ |
/* Is the thread still go? */ |
if (t->udebug.go == true) { |
/* |
* Yes, so clear go. As active == false, |
* this doesn't affect anything. |
*/ |
t->udebug.go = false; |
/* Answer GO call */ |
LOG("answer GO call with EVENT_FINISHED\n"); |
IPC_SET_RETVAL(t->udebug.go_call->data, 0); |
IPC_SET_ARG1(t->udebug.go_call->data, |
UDEBUG_EVENT_FINISHED); |
ipc_answer(&ta->answerbox, t->udebug.go_call); |
t->udebug.go_call = NULL; |
} else { |
/* |
* Debug_stop is already at initial value. |
* Yet this means the thread needs waking up. |
*/ |
/* |
* t's lock must not be held when calling |
* waitq_wakeup. |
*/ |
waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST); |
} |
} |
mutex_unlock(&t->udebug.lock); |
} |
ta->udebug.dt_state = UDEBUG_TS_INACTIVE; |
ta->udebug.debugger = NULL; |
return 0; |
} |
/** @} |
*/ |
/branches/network/kernel/generic/src/udebug/udebug_ops.c |
---|
0,0 → 1,524 |
/* |
* Copyright (c) 2008 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 generic |
* @{ |
*/ |
/** |
* @file |
* @brief Udebug operations. |
* |
* Udebug operations on tasks and threads are implemented here. The |
* functions defined here are called from the udebug_ipc module |
* when servicing udebug IPC messages. |
*/ |
#include <debug.h> |
#include <proc/task.h> |
#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> |
#include <udebug/udebug_ops.h> |
/** |
* Prepare a thread for a debugging operation. |
* |
* Simply put, return thread t with t->udebug.lock held, |
* but only if it verifies all conditions. |
* |
* Specifically, verifies that thread t exists, is a userspace thread, |
* and belongs to the current task (TASK). Verifies, that the thread |
* 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 |
* that the thread cannot leave the debugging session, let alone cease |
* to exist. |
* |
* In this function, holding the TASK->udebug.lock mutex prevents the |
* thread from leaving the debugging session, while relaxing from |
* the t->lock spinlock to the t->udebug.lock mutex. |
* |
* @param t Pointer, need not at all be valid. |
* @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 being_go) |
{ |
task_id_t taskid; |
ipl_t ipl; |
taskid = TASK->taskid; |
mutex_lock(&TASK->udebug.lock); |
/* thread_exists() must be called with threads_lock held */ |
ipl = interrupts_disable(); |
spinlock_lock(&threads_lock); |
if (!thread_exists(t)) { |
spinlock_unlock(&threads_lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
return ENOENT; |
} |
/* t->lock is enough to ensure the thread's existence */ |
spinlock_lock(&t->lock); |
spinlock_unlock(&threads_lock); |
/* Verify that 't' is a userspace thread. */ |
if ((t->flags & THREAD_FLAG_USPACE) == 0) { |
/* It's not, deny its existence */ |
spinlock_unlock(&t->lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
return ENOENT; |
} |
/* Verify debugging state. */ |
if (t->udebug.active != true) { |
/* Not in debugging session or undesired GO state */ |
spinlock_unlock(&t->lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
return ENOENT; |
} |
/* |
* 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. */ |
/* 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); |
return ENOENT; |
} |
/* |
* Now we need to grab the thread's debug lock for synchronization |
* of the threads stoppability/stop state. |
*/ |
mutex_lock(&t->udebug.lock); |
/* The big task mutex is no longer needed. */ |
mutex_unlock(&TASK->udebug.lock); |
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. */ |
return EOK; /* All went well. */ |
} |
/** End debugging operation on a thread. */ |
static void _thread_op_end(thread_t *t) |
{ |
mutex_unlock(&t->udebug.lock); |
} |
/** Begin debugging the current task. |
* |
* Initiates a debugging session for the current task (and its threads). |
* When the debugging session has started a reply will be sent to the |
* UDEBUG_BEGIN call. This may happen immediately in this function if |
* all the threads in this task are stoppable at the moment and in this |
* case the function returns 1. |
* |
* Otherwise the function returns 0 and the reply will be sent as soon as |
* all the threads become stoppable (i.e. they can be considered stopped). |
* |
* @param call The BEGIN call we are servicing. |
* @return 0 (OK, but not done yet), 1 (done) or negative error code. |
*/ |
int udebug_begin(call_t *call) |
{ |
int reply; |
thread_t *t; |
link_t *cur; |
LOG("udebug_begin()\n"); |
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; |
} |
TASK->udebug.dt_state = UDEBUG_TS_BEGINNING; |
TASK->udebug.begin_call = call; |
TASK->udebug.debugger = call->sender; |
if (TASK->udebug.not_stoppable_count == 0) { |
TASK->udebug.dt_state = UDEBUG_TS_ACTIVE; |
TASK->udebug.begin_call = NULL; |
reply = 1; /* immediate reply */ |
} else { |
reply = 0; /* no reply */ |
} |
/* 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); |
mutex_lock(&t->udebug.lock); |
if ((t->flags & THREAD_FLAG_USPACE) != 0) |
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; |
} |
/** Finish debugging the current task. |
* |
* Closes the debugging session for the current task. |
* @return Zero on success or negative error code. |
*/ |
int udebug_end(void) |
{ |
int rc; |
LOG("udebug_end()\n"); |
mutex_lock(&TASK->udebug.lock); |
LOG("task %" PRIu64 "\n", TASK->taskid); |
rc = udebug_task_cleanup(TASK); |
mutex_unlock(&TASK->udebug.lock); |
return rc; |
} |
/** Set the event mask. |
* |
* Sets the event mask that determines which events are enabled. |
* |
* @param mask Or combination of events that should be enabled. |
* @return Zero on success or negative error code. |
*/ |
int udebug_set_evmask(udebug_evmask_t mask) |
{ |
LOG("udebug_set_mask()\n"); |
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; |
} |
/** Give thread 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. |
* |
* @param t The thread to operate on (unlocked and need not be valid). |
* @param call The GO call that we are servicing. |
*/ |
int udebug_go(thread_t *t, call_t *call) |
{ |
int rc; |
/* On success, this will lock t->udebug.lock. */ |
rc = _thread_op_begin(t, false); |
if (rc != EOK) { |
return rc; |
} |
t->udebug.go_call = call; |
t->udebug.go = true; |
t->udebug.cur_event = 0; /* none */ |
/* |
* Neither t's lock nor threads_lock may be held during wakeup. |
*/ |
waitq_wakeup(&t->udebug.go_wq, WAKEUP_FIRST); |
_thread_op_end(t); |
return 0; |
} |
/** Stop a thread (i.e. take its GO away) |
* |
* Generates a STOP event as soon as the thread becomes stoppable (i.e. |
* can be considered stopped). |
* |
* @param t The thread to operate on (unlocked and need not be valid). |
* @param call The GO call that we are servicing. |
*/ |
int udebug_stop(thread_t *t, call_t *call) |
{ |
int rc; |
LOG("udebug_stop()\n"); |
/* |
* On success, this will lock t->udebug.lock. Note that this makes sure |
* the thread is not stopped. |
*/ |
rc = _thread_op_begin(t, true); |
if (rc != EOK) { |
return rc; |
} |
/* Take GO away from the thread. */ |
t->udebug.go = false; |
if (t->udebug.stoppable != true) { |
/* Answer will be sent when the thread becomes stoppable. */ |
_thread_op_end(t); |
return 0; |
} |
/* |
* Answer GO call. |
*/ |
LOG("udebug_stop - answering go call\n"); |
/* 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; |
} |
/** Read the list of userspace threads in the current task. |
* |
* The list takes the form of a sequence of thread hashes (i.e. the pointers |
* to thread structures). A buffer of size @a buf_size is allocated and |
* a pointer to it written to @a buffer. The sequence of hashes is written |
* into this buffer. |
* |
* If the sequence is longer than @a buf_size bytes, only as much hashes |
* as can fit are copied. The number of thread hashes copied is stored |
* in @a n. |
* |
* The rationale for having @a buf_size is that this function is only |
* used for servicing the THREAD_READ message, which always specifies |
* a maximum size for the userspace buffer. |
* |
* @param buffer The buffer for storing thread hashes. |
* @param buf_size Buffer size in bytes. |
* @param n The actual number of hashes copied will be stored here. |
*/ |
int udebug_thread_read(void **buffer, size_t buf_size, size_t *n) |
{ |
thread_t *t; |
link_t *cur; |
unative_t tid; |
unsigned copied_ids; |
ipl_t ipl; |
unative_t *id_buffer; |
int flags; |
size_t max_ids; |
LOG("udebug_thread_read()\n"); |
/* Allocate a buffer to hold thread IDs */ |
id_buffer = malloc(buf_size, 0); |
mutex_lock(&TASK->udebug.lock); |
/* Verify task state */ |
if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) { |
mutex_unlock(&TASK->udebug.lock); |
return EINVAL; |
} |
ipl = interrupts_disable(); |
spinlock_lock(&TASK->lock); |
/* Copy down the thread IDs */ |
max_ids = buf_size / sizeof(unative_t); |
copied_ids = 0; |
/* FIXME: make sure the thread isn't past debug shutdown... */ |
for (cur = TASK->th_head.next; cur != &TASK->th_head; cur = cur->next) { |
/* Do not write past end of buffer */ |
if (copied_ids >= max_ids) break; |
t = list_get_instance(cur, thread_t, th_link); |
spinlock_lock(&t->lock); |
flags = t->flags; |
spinlock_unlock(&t->lock); |
/* Not interested in kernel threads. */ |
if ((flags & THREAD_FLAG_USPACE) != 0) { |
/* Using thread struct pointer as identification hash */ |
tid = (unative_t) t; |
id_buffer[copied_ids++] = tid; |
} |
} |
spinlock_unlock(&TASK->lock); |
interrupts_restore(ipl); |
mutex_unlock(&TASK->udebug.lock); |
*buffer = id_buffer; |
*n = copied_ids * sizeof(unative_t); |
return 0; |
} |
/** Read the arguments of a system call. |
* |
* The arguments of the system call being being executed are copied |
* to an allocated buffer and a pointer to it is written to @a buffer. |
* The size of the buffer is exactly such that it can hold the maximum number |
* of system-call arguments. |
* |
* Unless the thread is currently blocked in a SYSCALL_B or SYSCALL_E event, |
* this function will fail with an EINVAL error code. |
* |
* @param buffer The buffer for storing thread hashes. |
*/ |
int udebug_args_read(thread_t *t, void **buffer) |
{ |
int rc; |
unative_t *arg_buffer; |
/* Prepare a buffer to hold the arguments. */ |
arg_buffer = malloc(6 * sizeof(unative_t), 0); |
/* 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. */ |
if (t->udebug.cur_event != UDEBUG_EVENT_SYSCALL_B && |
t->udebug.cur_event != UDEBUG_EVENT_SYSCALL_E) { |
_thread_op_end(t); |
return EINVAL; |
} |
/* Copy to a local buffer before releasing the lock. */ |
memcpy(arg_buffer, t->udebug.syscall_args, 6 * sizeof(unative_t)); |
_thread_op_end(t); |
*buffer = arg_buffer; |
return 0; |
} |
/** Read the memory of the debugged task. |
* |
* Reads @a n bytes from the address space of the debugged task, starting |
* from @a uspace_addr. The bytes are copied into an allocated buffer |
* and a pointer to it is written into @a buffer. |
* |
* @param uspace_addr Address from where to start reading. |
* @param n Number of bytes to read. |
* @param buffer For storing a pointer to the allocated buffer. |
*/ |
int udebug_mem_read(unative_t uspace_addr, size_t n, void **buffer) |
{ |
void *data_buffer; |
int rc; |
/* Verify task state */ |
mutex_lock(&TASK->udebug.lock); |
if (TASK->udebug.dt_state != UDEBUG_TS_ACTIVE) { |
mutex_unlock(&TASK->udebug.lock); |
return EBUSY; |
} |
data_buffer = malloc(n, 0); |
/* NOTE: this is not strictly from a syscall... but that shouldn't |
* be a problem */ |
rc = copy_from_uspace(data_buffer, (void *)uspace_addr, n); |
mutex_unlock(&TASK->udebug.lock); |
if (rc != 0) return rc; |
*buffer = data_buffer; |
return 0; |
} |
/** @} |
*/ |
/branches/network/kernel/generic/src/udebug/udebug_ipc.c |
---|
0,0 → 1,343 |
/* |
* Copyright (c) 2008 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 generic |
* @{ |
*/ |
/** |
* @file |
* @brief Udebug IPC message handling. |
* |
* This module handles udebug IPC messages and calls the appropriate |
* functions from the udebug_ops module which implement them. |
*/ |
#include <proc/task.h> |
#include <proc/thread.h> |
#include <arch.h> |
#include <errno.h> |
#include <ipc/ipc.h> |
#include <syscall/copy.h> |
#include <udebug/udebug.h> |
#include <udebug/udebug_ops.h> |
#include <udebug/udebug_ipc.h> |
int udebug_request_preprocess(call_t *call, phone_t *phone) |
{ |
switch (IPC_GET_ARG1(call->data)) { |
/* future UDEBUG_M_REGS_WRITE, UDEBUG_M_MEM_WRITE: */ |
default: |
break; |
} |
return 0; |
} |
/** Process a BEGIN call. |
* |
* Initiates a debugging session for the current task. The reply |
* to this call may or may not be sent before this function returns. |
* |
* @param call The call structure. |
*/ |
static void udebug_receive_begin(call_t *call) |
{ |
int rc; |
rc = udebug_begin(call); |
if (rc < 0) { |
IPC_SET_RETVAL(call->data, rc); |
ipc_answer(&TASK->kb.box, call); |
return; |
} |
/* |
* If the initialization of the debugging session has finished, |
* send a reply. |
*/ |
if (rc != 0) { |
IPC_SET_RETVAL(call->data, 0); |
ipc_answer(&TASK->kb.box, call); |
} |
} |
/** Process an END call. |
* |
* Terminates the debugging session for the current task. |
* @param call The call structure. |
*/ |
static void udebug_receive_end(call_t *call) |
{ |
int rc; |
rc = udebug_end(); |
IPC_SET_RETVAL(call->data, rc); |
ipc_answer(&TASK->kb.box, call); |
} |
/** Process a SET_EVMASK call. |
* |
* Sets an event mask for the current debugging session. |
* @param call The call structure. |
*/ |
static void udebug_receive_set_evmask(call_t *call) |
{ |
int rc; |
udebug_evmask_t mask; |
mask = IPC_GET_ARG2(call->data); |
rc = udebug_set_evmask(mask); |
IPC_SET_RETVAL(call->data, rc); |
ipc_answer(&TASK->kb.box, call); |
} |
/** Process a GO call. |
* |
* Resumes execution of the specified thread. |
* @param call The call structure. |
*/ |
static void udebug_receive_go(call_t *call) |
{ |
thread_t *t; |
int rc; |
t = (thread_t *)IPC_GET_ARG2(call->data); |
rc = udebug_go(t, call); |
if (rc < 0) { |
IPC_SET_RETVAL(call->data, rc); |
ipc_answer(&TASK->kb.box, call); |
return; |
} |
} |
/** Process a STOP call. |
* |
* Suspends execution of the specified thread. |
* @param call The call structure. |
*/ |
static void udebug_receive_stop(call_t *call) |
{ |
thread_t *t; |
int rc; |
t = (thread_t *)IPC_GET_ARG2(call->data); |
rc = udebug_stop(t, call); |
IPC_SET_RETVAL(call->data, rc); |
ipc_answer(&TASK->kb.box, call); |
} |
/** Process a THREAD_READ call. |
* |
* Reads the list of hashes of the (userspace) threads in the current task. |
* @param call The call structure. |
*/ |
static void udebug_receive_thread_read(call_t *call) |
{ |
unative_t uspace_addr; |
unative_t to_copy; |
unsigned total_bytes; |
unsigned buf_size; |
void *buffer; |
size_t n; |
int rc; |
uspace_addr = IPC_GET_ARG2(call->data); /* Destination address */ |
buf_size = IPC_GET_ARG3(call->data); /* Dest. buffer size */ |
/* |
* Read thread list. Variable n will be filled with actual number |
* of threads times thread-id size. |
*/ |
rc = udebug_thread_read(&buffer, buf_size, &n); |
if (rc < 0) { |
IPC_SET_RETVAL(call->data, rc); |
ipc_answer(&TASK->kb.box, call); |
return; |
} |
total_bytes = n; |
/* Copy MAX(buf_size, total_bytes) bytes */ |
if (buf_size > total_bytes) |
to_copy = total_bytes; |
else |
to_copy = buf_size; |
/* |
* Make use of call->buffer to transfer data to caller's userspace |
*/ |
IPC_SET_RETVAL(call->data, 0); |
/* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that |
same code in process_answer() can be used |
(no way to distinguish method in answer) */ |
IPC_SET_ARG1(call->data, uspace_addr); |
IPC_SET_ARG2(call->data, to_copy); |
IPC_SET_ARG3(call->data, total_bytes); |
call->buffer = buffer; |
ipc_answer(&TASK->kb.box, call); |
} |
/** Process an ARGS_READ call. |
* |
* Reads the argument of a current syscall event (SYSCALL_B or SYSCALL_E). |
* @param call The call structure. |
*/ |
static void udebug_receive_args_read(call_t *call) |
{ |
thread_t *t; |
unative_t uspace_addr; |
int rc; |
void *buffer; |
t = (thread_t *)IPC_GET_ARG2(call->data); |
rc = udebug_args_read(t, &buffer); |
if (rc != EOK) { |
IPC_SET_RETVAL(call->data, rc); |
ipc_answer(&TASK->kb.box, call); |
return; |
} |
/* |
* Make use of call->buffer to transfer data to caller's userspace |
*/ |
uspace_addr = IPC_GET_ARG3(call->data); |
IPC_SET_RETVAL(call->data, 0); |
/* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that |
same code in process_answer() can be used |
(no way to distinguish method in answer) */ |
IPC_SET_ARG1(call->data, uspace_addr); |
IPC_SET_ARG2(call->data, 6 * sizeof(unative_t)); |
call->buffer = buffer; |
ipc_answer(&TASK->kb.box, call); |
} |
/** Process an MEM_READ call. |
* |
* Reads memory of the current (debugged) task. |
* @param call The call structure. |
*/ |
static void udebug_receive_mem_read(call_t *call) |
{ |
unative_t uspace_dst; |
unative_t uspace_src; |
unsigned size; |
void *buffer; |
int rc; |
uspace_dst = IPC_GET_ARG2(call->data); |
uspace_src = IPC_GET_ARG3(call->data); |
size = IPC_GET_ARG4(call->data); |
rc = udebug_mem_read(uspace_src, size, &buffer); |
if (rc < 0) { |
IPC_SET_RETVAL(call->data, rc); |
ipc_answer(&TASK->kb.box, call); |
return; |
} |
IPC_SET_RETVAL(call->data, 0); |
/* ARG1=dest, ARG2=size as in IPC_M_DATA_READ so that |
same code in process_answer() can be used |
(no way to distinguish method in answer) */ |
IPC_SET_ARG1(call->data, uspace_dst); |
IPC_SET_ARG2(call->data, size); |
call->buffer = buffer; |
ipc_answer(&TASK->kb.box, call); |
} |
/** Handle a debug call received on the kernel answerbox. |
* |
* This is called by the kbox servicing thread. Verifies that the sender |
* is indeed the debugger and calls the appropriate processing function. |
*/ |
void udebug_call_receive(call_t *call) |
{ |
int debug_method; |
debug_method = IPC_GET_ARG1(call->data); |
if (debug_method != UDEBUG_M_BEGIN) { |
/* |
* Verify that the sender is this task's debugger. |
* Note that this is the only thread that could change |
* TASK->debugger. Therefore no locking is necessary |
* and the sender can be safely considered valid until |
* control exits this function. |
*/ |
if (TASK->udebug.debugger != call->sender) { |
IPC_SET_RETVAL(call->data, EINVAL); |
ipc_answer(&TASK->kb.box, call); |
return; |
} |
} |
switch (debug_method) { |
case UDEBUG_M_BEGIN: |
udebug_receive_begin(call); |
break; |
case UDEBUG_M_END: |
udebug_receive_end(call); |
break; |
case UDEBUG_M_SET_EVMASK: |
udebug_receive_set_evmask(call); |
break; |
case UDEBUG_M_GO: |
udebug_receive_go(call); |
break; |
case UDEBUG_M_STOP: |
udebug_receive_stop(call); |
break; |
case UDEBUG_M_THREAD_READ: |
udebug_receive_thread_read(call); |
break; |
case UDEBUG_M_ARGS_READ: |
udebug_receive_args_read(call); |
break; |
case UDEBUG_M_MEM_READ: |
udebug_receive_mem_read(call); |
break; |
} |
} |
/** @} |
*/ |
/branches/network/kernel/Makefile |
---|
30,23 → 30,27 |
## 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)" |
GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) \ |
GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \ |
-fno-builtin -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Werror \ |
-nostdlib -nostdinc |
-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 → 62,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,72 → 80,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 |
## Simple detection for the type of the host system |
# |
HOST = $(shell uname) |
174,6 → 104,7 |
OBJDUMP = $(BINUTILS_PREFIX)objdump |
LIBDIR = /usr/lib |
CFLAGS = $(GCC_CFLAGS) |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
ifeq ($(COMPILER),icc_native) |
185,6 → 116,7 |
OBJDUMP = objdump |
LIBDIR = /usr/lib |
CFLAGS = $(ICC_CFLAGS) |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
ifeq ($(COMPILER),suncc_native) |
196,6 → 128,8 |
OBJDUMP = $(BINUTILS_PREFIX)objdump |
LIBDIR = /usr/lib |
CFLAGS = $(SUNCC_CFLAGS) |
DEFS += $(CONFIG_DEFS) |
DEPEND_DEFS = $(DEFS) |
endif |
ifeq ($(COMPILER),gcc_cross) |
207,6 → 141,7 |
OBJDUMP = $(TOOLCHAIN_DIR)/bin/$(TARGET)-objdump |
LIBDIR = $(TOOLCHAIN_DIR)/lib |
CFLAGS = $(GCC_CFLAGS) |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
## Generic kernel sources |
220,12 → 155,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 \ |
252,6 → 186,7 |
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 \ |
261,7 → 196,6 |
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 \ |
283,11 → 217,30 |
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 |
# |
ifeq ($(CONFIG_UDEBUG),y) |
GENERIC_SOURCES += \ |
generic/src/ipc/kbox.c \ |
generic/src/udebug/udebug.c \ |
generic/src/udebug/udebug_ops.c \ |
generic/src/udebug/udebug_ipc.c |
endif |
## Test sources |
# |
ifeq ($(CONFIG_TEST),y) |
DEFS += -DCONFIG_TEST |
CFLAGS += -Itest/ |
GENERIC_SOURCES += \ |
test/test.c \ |
294,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 \ |
315,6 → 263,58 |
test/print/print1.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))) |
321,25 → 321,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 ; \ |
346,24 → 345,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 |
370,8 → 369,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/network/kernel/arch/ppc64/include/elf.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/memstr.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/arg.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/atomic.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/arch.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/proc/task.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/proc/thread.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/boot/boot.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/faddr.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/asm.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/mm/asid.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/mm/tlb.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/mm/as.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/mm/frame.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/mm/page.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/context.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/debug.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/barrier.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/cpu.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/drivers/pic.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/asm/regname.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/context_offset.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/interrupt.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/fpu_context.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/exception.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/cycle.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/byteorder.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/cpuid.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/include/types.h |
---|
File deleted |
/branches/network/kernel/arch/ppc64/Makefile.inc |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/dummy.s |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/interrupt.c |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/ppc64.c |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/drivers/pic.c |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/exception.S |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/fpu_context.S |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/ddi/ddi.c |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/asm.S |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/proc/scheduler.c |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/boot/boot.S |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/context.S |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/debug/panic.s |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/cpu/cpu.c |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/mm/frame.c |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/mm/page.c |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/mm/tlb.c |
---|
File deleted |
/branches/network/kernel/arch/ppc64/src/mm/as.c |
---|
File deleted |
/branches/network/kernel/arch/ppc64/_link.ld.in |
---|
File deleted |
/branches/network/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/network/kernel/arch/ia32xen/include/drivers/xconsole.h |
---|
File deleted |
/branches/network/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/network/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/network/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/network/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/network/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/network/kernel/arch/ia32xen/include/types.h |
---|
File deleted |
/branches/network/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/network/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/network/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/network/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/network/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/network/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/network/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/network/kernel/arch/ia32xen/include/pm.h |
---|
File deleted |
/branches/network/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/network/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/network/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/network/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/network/kernel/arch/ia32xen/include/asm.h |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/include/hypercall.h |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/include/mm/page.h |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/include/mm/asid.h |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/include/mm/tlb.h |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/include/mm/as.h |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/include/mm/frame.h |
---|
File deleted |
/branches/network/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/network/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/network/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/network/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/network/kernel/arch/ia32xen/Makefile.inc |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/ia32xen.c |
---|
File deleted |
/branches/network/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/network/kernel/arch/ia32xen/src/pm.c |
---|
File deleted |
/branches/network/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/network/kernel/arch/ia32xen/src/smp/mps.c |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/smp/smp.c |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/smp/ipi.c |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/smp/apic.c |
---|
File deleted |
/branches/network/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/network/kernel/arch/ia32xen/src/boot/boot.S |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/proc/thread.c |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/proc/scheduler.c |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/proc/task.c |
---|
File deleted |
/branches/network/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/network/kernel/arch/ia32xen/src/mm/tlb.c |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/mm/as.c |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/mm/frame.c |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/mm/page.c |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/userspace.c |
---|
File deleted |
/branches/network/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/network/kernel/arch/ia32xen/src/interrupt.c |
---|
File deleted |
/branches/network/kernel/arch/ia32xen/src/drivers/xconsole.c |
---|
File deleted |
/branches/network/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/network/kernel/arch/ia32xen/src/asm.S |
---|
File deleted |
/branches/network/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/network/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/network/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/network/kernel/arch/ia32xen/_link.ld.in |
---|
File deleted |
/branches/network/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/network/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/network/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/network/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/network/kernel/arch/sparc64/include/types.h |
---|
57,6 → 57,9 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef struct { |
} fncptr_t; |
/**< Formats for uintptr_t, size_t, count_t and index_t */ |
#define PRIp "llx" |
#define PRIs "llu" |
/branches/network/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/network/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/network/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/network/kernel/arch/sparc64/include/trap/syscall.h |
---|
31,26 → 31,14 |
*/ |
/** |
* @file |
* @brief This file contains the trap_instruction handler. |
* |
* The trap_instruction trap is used to implement syscalls. |
* @brief |
*/ |
#ifndef KERN_sparc64_SYSCALL_TRAP_H_ |
#define KERN_sparc64_SYSCALL_TRAP_H_ |
#define TT_TRAP_INSTRUCTION(n) (0x100 + (n)) |
#define TT_TRAP_INSTRUCTION_LAST TT_TRAP_INSTRUCTION(127) |
#define TT_TRAP_INSTRUCTION_0 0x100 |
#ifdef __ASM__ |
.macro TRAP_INSTRUCTION n |
ba trap_instruction_handler |
mov TT_TRAP_INSTRUCTION(\n) - TT_TRAP_INSTRUCTION(0), %g2 |
.endm |
#endif /* __ASM__ */ |
#endif |
/** @} |
/branches/network/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/network/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/network/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)); |
}; |
/branches/network/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/network/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/network/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/network/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) |
{ |
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) |
{ |
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) |
{ |
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) |
{ |
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) |
{ |
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) |
{ |
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, index_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, index_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, index_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, index_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, index_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, index_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/network/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/network/kernel/arch/sparc64/include/mm/tsb.h |
---|
107,6 → 107,55 |
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; |
/branches/network/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/network/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/network/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/network/kernel/arch/sparc64/include/drivers/z8530.h |
---|
File deleted |
/branches/network/kernel/arch/sparc64/include/drivers/ns16550.h |
---|
File deleted |
/branches/network/kernel/arch/sparc64/include/drivers/sgcn.h |
---|
0,0 → 1,127 |
/* |
* 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> |
/* number of bytes in the TOC magic, including the terminating '\0' */ |
#define TOC_MAGIC_BYTES 8 |
/* number of bytes in the TOC key, including the terminating '\0' */ |
#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 terminating '\0' */ |
#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; |
void sgcn_grab(void); |
void sgcn_release(void); |
indev_t *sgcnin_init(void); |
void sgcnout_init(void); |
#endif |
/** @} |
*/ |
/branches/network/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/network/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/network/kernel/arch/sparc64/include/drivers/kbd.h |
---|
41,7 → 41,8 |
typedef enum { |
KBD_UNKNOWN, |
KBD_Z8530, |
KBD_NS16550 |
KBD_NS16550, |
KBD_SGCN |
} kbd_type_t; |
extern kbd_type_t kbd_type; |
/branches/network/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/network/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/network/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 |
46,80 → 42,55 |
DEFS += -D__64_BITS__ |
## 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/network/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 |
61,15 → 63,55 |
ofw_tree_node_t *node; |
count_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/network/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/network/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/network/kernel/arch/sparc64/src/console.c |
---|
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,89 → 48,98 |
#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 |
indev_t *kbrdin; |
kbrdin = sgcnin_init(); |
if (kbrdin) |
srlnin_init(kbrdin); |
#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) || (strcmp(prop->value, "/sgcn") != 0)) { |
standard_console_init(aliases); |
} else { |
serengeti_init(); |
} |
} |
/** Acquire console back for kernel |
* |
*/ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
scr_redraw(); |
#endif |
switch (kbd_type) { |
#ifdef CONFIG_Z8530 |
case KBD_Z8530: |
z8530_grab(); |
#ifdef CONFIG_SGCN |
case KBD_SGCN: |
sgcn_grab(); |
break; |
#endif |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
ns16550_grab(); |
break; |
#endif |
default: |
break; |
} |
148,16 → 151,11 |
void arch_release_console(void) |
{ |
switch (kbd_type) { |
#ifdef CONFIG_Z8530 |
case KBD_Z8530: |
z8530_release(); |
#ifdef CONFIG_SGCN |
case KBD_SGCN: |
sgcn_release(); |
break; |
#endif |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
ns16550_release(); |
break; |
#endif |
default: |
break; |
} |
/branches/network/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/network/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; |
strncpy(init.tasks[i].name, bootinfo.taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
/* 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/network/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/network/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/network/kernel/arch/sparc64/src/trap/trap_table.S |
---|
329,198 → 329,22 |
fill_1_normal_tl0: |
FILL_NORMAL_HANDLER_USERSPACE |
/* TT = 0x100, TL = 0, trap_instruction_0 */ |
.org trap_table + TT_TRAP_INSTRUCTION(0)*ENTRY_SIZE |
.global trap_instruction_0_tl0 |
trap_instruction_0_tl0: |
TRAP_INSTRUCTION 0 |
/* TT = 0x100 - 0x17f, TL = 0, trap_instruction_0 - trap_instruction_7f */ |
.irp cur, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\ |
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\ |
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,\ |
58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\ |
77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\ |
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,\ |
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,\ |
127 |
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE |
.global trap_instruction_\cur\()_tl0 |
trap_instruction_\cur\()_tl0: |
ba trap_instruction_handler |
mov \cur, %g2 |
.endr |
/* TT = 0x101, TL = 0, trap_instruction_1 */ |
.org trap_table + TT_TRAP_INSTRUCTION(1)*ENTRY_SIZE |
.global trap_instruction_1_tl0 |
trap_instruction_1_tl0: |
TRAP_INSTRUCTION 1 |
/* TT = 0x102, TL = 0, trap_instruction_2 */ |
.org trap_table + TT_TRAP_INSTRUCTION(2)*ENTRY_SIZE |
.global trap_instruction_2_tl0 |
trap_instruction_2_tl0: |
TRAP_INSTRUCTION 2 |
/* TT = 0x103, TL = 0, trap_instruction_3 */ |
.org trap_table + TT_TRAP_INSTRUCTION(3)*ENTRY_SIZE |
.global trap_instruction_3_tl0 |
trap_instruction_3_tl0: |
TRAP_INSTRUCTION 3 |
/* TT = 0x104, TL = 0, trap_instruction_4 */ |
.org trap_table + TT_TRAP_INSTRUCTION(4)*ENTRY_SIZE |
.global trap_instruction_4_tl0 |
trap_instruction_4_tl0: |
TRAP_INSTRUCTION 4 |
/* TT = 0x105, TL = 0, trap_instruction_5 */ |
.org trap_table + TT_TRAP_INSTRUCTION(5)*ENTRY_SIZE |
.global trap_instruction_5_tl0 |
trap_instruction_5_tl0: |
TRAP_INSTRUCTION 5 |
/* TT = 0x106, TL = 0, trap_instruction_6 */ |
.org trap_table + TT_TRAP_INSTRUCTION(6)*ENTRY_SIZE |
.global trap_instruction_6_tl0 |
trap_instruction_6_tl0: |
TRAP_INSTRUCTION 6 |
/* TT = 0x107, TL = 0, trap_instruction_7 */ |
.org trap_table + TT_TRAP_INSTRUCTION(7)*ENTRY_SIZE |
.global trap_instruction_7_tl0 |
trap_instruction_7_tl0: |
TRAP_INSTRUCTION 7 |
/* TT = 0x108, TL = 0, trap_instruction_8 */ |
.org trap_table + TT_TRAP_INSTRUCTION(8)*ENTRY_SIZE |
.global trap_instruction_8_tl0 |
trap_instruction_8_tl0: |
TRAP_INSTRUCTION 8 |
/* TT = 0x109, TL = 0, trap_instruction_9 */ |
.org trap_table + TT_TRAP_INSTRUCTION(9)*ENTRY_SIZE |
.global trap_instruction_9_tl0 |
trap_instruction_9_tl0: |
TRAP_INSTRUCTION 9 |
/* TT = 0x10a, TL = 0, trap_instruction_10 */ |
.org trap_table + TT_TRAP_INSTRUCTION(10)*ENTRY_SIZE |
.global trap_instruction_10_tl0 |
trap_instruction_10_tl0: |
TRAP_INSTRUCTION 10 |
/* TT = 0x10b, TL = 0, trap_instruction_11 */ |
.org trap_table + TT_TRAP_INSTRUCTION(11)*ENTRY_SIZE |
.global trap_instruction_11_tl0 |
trap_instruction_11_tl0: |
TRAP_INSTRUCTION 11 |
/* TT = 0x10c, TL = 0, trap_instruction_12 */ |
.org trap_table + TT_TRAP_INSTRUCTION(12)*ENTRY_SIZE |
.global trap_instruction_12_tl0 |
trap_instruction_12_tl0: |
TRAP_INSTRUCTION 12 |
/* TT = 0x10d, TL = 0, trap_instruction_13 */ |
.org trap_table + TT_TRAP_INSTRUCTION(13)*ENTRY_SIZE |
.global trap_instruction_13_tl0 |
trap_instruction_13_tl0: |
TRAP_INSTRUCTION 13 |
/* TT = 0x10e, TL = 0, trap_instruction_14 */ |
.org trap_table + TT_TRAP_INSTRUCTION(14)*ENTRY_SIZE |
.global trap_instruction_14_tl0 |
trap_instruction_14_tl0: |
TRAP_INSTRUCTION 14 |
/* TT = 0x10f, TL = 0, trap_instruction_15 */ |
.org trap_table + TT_TRAP_INSTRUCTION(15)*ENTRY_SIZE |
.global trap_instruction_15_tl0 |
trap_instruction_15_tl0: |
TRAP_INSTRUCTION 15 |
/* TT = 0x110, TL = 0, trap_instruction_16 */ |
.org trap_table + TT_TRAP_INSTRUCTION(16)*ENTRY_SIZE |
.global trap_instruction_16_tl0 |
trap_instruction_16_tl0: |
TRAP_INSTRUCTION 16 |
/* TT = 0x111, TL = 0, trap_instruction_17 */ |
.org trap_table + TT_TRAP_INSTRUCTION(17)*ENTRY_SIZE |
.global trap_instruction_17_tl0 |
trap_instruction_17_tl0: |
TRAP_INSTRUCTION 17 |
/* TT = 0x112, TL = 0, trap_instruction_18 */ |
.org trap_table + TT_TRAP_INSTRUCTION(18)*ENTRY_SIZE |
.global trap_instruction_18_tl0 |
trap_instruction_18_tl0: |
TRAP_INSTRUCTION 18 |
/* TT = 0x113, TL = 0, trap_instruction_19 */ |
.org trap_table + TT_TRAP_INSTRUCTION(19)*ENTRY_SIZE |
.global trap_instruction_19_tl0 |
trap_instruction_19_tl0: |
TRAP_INSTRUCTION 19 |
/* TT = 0x114, TL = 0, trap_instruction_20 */ |
.org trap_table + TT_TRAP_INSTRUCTION(20)*ENTRY_SIZE |
.global trap_instruction_20_tl0 |
trap_instruction_20_tl0: |
TRAP_INSTRUCTION 20 |
/* TT = 0x115, TL = 0, trap_instruction_21 */ |
.org trap_table + TT_TRAP_INSTRUCTION(21)*ENTRY_SIZE |
.global trap_instruction_21_tl0 |
trap_instruction_21_tl0: |
TRAP_INSTRUCTION 21 |
/* TT = 0x116, TL = 0, trap_instruction_22 */ |
.org trap_table + TT_TRAP_INSTRUCTION(22)*ENTRY_SIZE |
.global trap_instruction_22_tl0 |
trap_instruction_22_tl0: |
TRAP_INSTRUCTION 22 |
/* TT = 0x117, TL = 0, trap_instruction_23 */ |
.org trap_table + TT_TRAP_INSTRUCTION(23)*ENTRY_SIZE |
.global trap_instruction_23_tl0 |
trap_instruction_23_tl0: |
TRAP_INSTRUCTION 23 |
/* TT = 0x118, TL = 0, trap_instruction_24 */ |
.org trap_table + TT_TRAP_INSTRUCTION(24)*ENTRY_SIZE |
.global trap_instruction_24_tl0 |
trap_instruction_24_tl0: |
TRAP_INSTRUCTION 24 |
/* TT = 0x119, TL = 0, trap_instruction_25 */ |
.org trap_table + TT_TRAP_INSTRUCTION(25)*ENTRY_SIZE |
.global trap_instruction_25_tl0 |
trap_instruction_25_tl0: |
TRAP_INSTRUCTION 25 |
/* TT = 0x11a, TL = 0, trap_instruction_26 */ |
.org trap_table + TT_TRAP_INSTRUCTION(26)*ENTRY_SIZE |
.global trap_instruction_26_tl0 |
trap_instruction_26_tl0: |
TRAP_INSTRUCTION 26 |
/* TT = 0x11b, TL = 0, trap_instruction_27 */ |
.org trap_table + TT_TRAP_INSTRUCTION(27)*ENTRY_SIZE |
.global trap_instruction_27_tl0 |
trap_instruction_27_tl0: |
TRAP_INSTRUCTION 27 |
/* TT = 0x11c, TL = 0, trap_instruction_28 */ |
.org trap_table + TT_TRAP_INSTRUCTION(28)*ENTRY_SIZE |
.global trap_instruction_28_tl0 |
trap_instruction_28_tl0: |
TRAP_INSTRUCTION 28 |
/* TT = 0x11d, TL = 0, trap_instruction_29 */ |
.org trap_table + TT_TRAP_INSTRUCTION(29)*ENTRY_SIZE |
.global trap_instruction_29_tl0 |
trap_instruction_29_tl0: |
TRAP_INSTRUCTION 29 |
/* TT = 0x11e, TL = 0, trap_instruction_30 */ |
.org trap_table + TT_TRAP_INSTRUCTION(30)*ENTRY_SIZE |
.global trap_instruction_30_tl0 |
trap_instruction_30_tl0: |
TRAP_INSTRUCTION 30 |
/* TT = 0x11f, TL = 0, trap_instruction_31 */ |
.org trap_table + TT_TRAP_INSTRUCTION(31)*ENTRY_SIZE |
.global trap_instruction_31_tl0 |
trap_instruction_31_tl0: |
TRAP_INSTRUCTION 31 |
/* |
* Handlers for TL>0. |
*/ |
782,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 |
924,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 0f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill |
nop |
add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7 |
/branches/network/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/network/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 *, index_t, bool); |
static void itlb_pte_copy(pte_t *, index_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,10 → 125,10 |
/** 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) |
{ |
165,8 → 164,8 |
/** 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) |
{ |
235,10 → 234,11 |
* 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) |
{ |
287,10 → 287,11 |
/** 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) |
{ |
331,6 → 332,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 → 363,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 → 370,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 → 436,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 → 452,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 → 468,71 |
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 (US3) |
/** Invalidates given TLB entry if and only if it is non-locked or global. |
* |
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1, |
* TLB_ISMALL, TLB_IBIG). |
* @param entry Entry index within the given TLB. |
*/ |
static void tlb_invalidate_entry(int tlb, index_t entry) |
{ |
tlb_data_t d; |
tlb_tag_read_reg_t t; |
if (tlb == TLB_DSMALL || tlb == TLB_DBIG_0 || tlb == TLB_DBIG_1) { |
d.value = dtlb_data_access_read(tlb, entry); |
if (!d.l || d.g) { |
t.value = dtlb_tag_read_read(tlb, entry); |
d.v = false; |
dtlb_tag_access_write(t.value); |
dtlb_data_access_write(tlb, entry, d.value); |
} |
} else if (tlb == TLB_ISMALL || tlb == TLB_IBIG) { |
d.value = itlb_data_access_read(tlb, entry); |
if (!d.l || d.g) { |
t.value = itlb_tag_read_read(tlb, entry); |
d.v = false; |
itlb_tag_access_write(t.value); |
itlb_data_access_write(tlb, entry, d.value); |
} |
} |
} |
#endif |
/** 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. |
*/ |
#if defined (US) |
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 → 542,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,7 → 552,21 |
dtlb_data_access_write(i, d.value); |
} |
} |
#elif defined (US3) |
for (i = 0; i < tlb_ismall_size(); i++) |
tlb_invalidate_entry(TLB_ISMALL, i); |
for (i = 0; i < tlb_ibig_size(); i++) |
tlb_invalidate_entry(TLB_IBIG, i); |
for (i = 0; i < tlb_dsmall_size(); i++) |
tlb_invalidate_entry(TLB_DSMALL, i); |
for (i = 0; i < tlb_dbig_size(); i++) |
tlb_invalidate_entry(TLB_DBIG_0, i); |
for (i = 0; i < tlb_dbig_size(); i++) |
tlb_invalidate_entry(TLB_DBIG_1, i); |
#endif |
} |
/** Invalidate all ITLB and DTLB entries that belong to specified ASID |
484,9 → 596,9 |
/** 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) |
{ |
/branches/network/kernel/arch/sparc64/src/mm/as.c |
---|
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/network/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/network/kernel/arch/sparc64/src/mm/tsb.c |
---|
112,9 → 112,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(); |
173,3 → 173,4 |
/** @} |
*/ |
/branches/network/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,6 |
*/ |
frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1); |
} |
} |
/** @} |
/branches/network/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. This argument is |
* ignored. |
* |
* @return Virtual address of the page where the device is mapped. |
* @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/network/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; |
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/network/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,22 → 34,30 |
#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 |
63,7 → 71,16 |
uintptr_t aligned_addr; |
ofw_tree_property_t *prop; |
const char *name; |
cir_t cir; |
void *cir_arg; |
#ifdef CONFIG_NS16550 |
ns16550_t *ns16550; |
#endif |
#ifdef CONFIG_Z8530 |
z8530_t *z8530; |
#endif |
name = ofw_tree_node_name(node); |
/* |
84,30 → 101,32 |
*/ |
uint32_t interrupts; |
prop = ofw_tree_getprop(node, "interrupts"); |
if (!prop || !prop->value) |
panic("Can't find \"interrupts\" property.\n"); |
if ((!prop) || (!prop->value)) |
panic("Cannot find 'interrupt' property."); |
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)) |
panic("Cannot find 'reg' property."); |
uintptr_t pa; |
size_t size; |
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)) { |
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)) { |
if (!ofw_fhc_map_interrupt(node->parent, |
((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
} |
115,18 → 134,20 |
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)) { |
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)) { |
if (!ofw_ebus_map_interrupt(node->parent, |
((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
}; |
break; |
default: |
panic("Unexpected type.\n"); |
panic("Unexpected keyboard type."); |
} |
/* |
137,23 → 158,57 |
*/ |
aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
offset = pa - aligned_addr; |
uintptr_t vaddr = hw_map(aligned_addr, offset + size) + offset; |
switch (kbd_type) { |
#ifdef CONFIG_Z8530 |
case KBD_Z8530: |
z8530_init(devno, inr, vaddr); |
z8530 = (z8530_t *) hw_map(aligned_addr, offset + size) + |
offset; |
indev_t *kbrdin_z8530 = z8530_init(z8530, inr, cir, cir_arg); |
if (kbrdin_z8530) |
kbrd_init(kbrdin_z8530); |
/* |
* 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.type", NULL, KBD_Z8530); |
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); |
break; |
#endif |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
ns16550_init(devno, inr, vaddr); |
ns16550 = (ns16550_t *) hw_map(aligned_addr, offset + size) + |
offset; |
indev_t *kbrdin_ns16550 = ns16550_init(ns16550, inr, cir, cir_arg); |
if (kbrdin_ns16550) |
kbrd_init(kbrdin_ns16550); |
/* |
* 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.type", NULL, KBD_NS16550); |
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); |
break; |
#endif |
default: |
printf("Kernel is not compiled with the necessary keyboard driver this machine requires.\n"); |
printf("Kernel is not compiled with the necessary keyboard " |
"driver this machine requires.\n"); |
} |
} |
#endif |
/** @} |
*/ |
/branches/network/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,6 → 55,10 |
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); |
61,6 → 65,8 |
if (strcmp(name, "SUNW,m64B") == 0) |
scr_type = SCR_ATYFB; |
else if (strcmp(name, "SUNW,XVR-100") == 0) |
scr_type = SCR_XVR; |
else if (strcmp(name, "SUNW,ffb") == 0) |
scr_type = SCR_FFB; |
else if (strcmp(name, "cgsix") == 0) |
67,11 → 73,12 |
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/network/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/network/kernel/arch/sparc64/src/drivers/sgcn.c |
---|
0,0 → 1,383 |
/* |
* 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)) |
/** defined in drivers/kbd.c */ |
extern kbd_type_t kbd_type; |
/** 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 char, bool); |
/** SGCN output device operations */ |
static outdev_operations_t sgcnout_ops = { |
.write = sgcn_putchar |
}; |
/** SGCN input device operations */ |
static indev_operations_t sgcnin_ops = { |
.poll = NULL |
}; |
static indev_t sgcnin; /**< SGCN input device. */ |
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(strcmp(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 (strcmp(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. If the line |
* feed character is written ('\n'), the carriage return character ('\r') is |
* written straight away. |
*/ |
static void sgcn_putchar(outdev_t *od, const char c, bool silent) |
{ |
if (!silent) { |
spinlock_lock(&sgcn_output_lock); |
sgcn_do_putchar(c); |
if (c == '\n') |
sgcn_do_putchar('\r'); |
spinlock_unlock(&sgcn_output_lock); |
} |
} |
/** |
* Grabs the input for kernel. |
*/ |
void sgcn_grab(void) |
{ |
kbd_disabled = true; |
} |
/** |
* 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() |
{ |
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(&sgcnin, c); |
} |
spinlock_unlock(&sgcn_input_lock); |
} |
/** |
* Polling thread function. |
*/ |
static void kkbdpoll(void *arg) { |
while (1) { |
if (!silent) { |
sgcn_poll(); |
} |
thread_usleep(POLL_INTERVAL); |
} |
} |
/** |
* A public function which initializes input from the Serengeti console. |
*/ |
indev_t *sgcnin_init(void) |
{ |
sgcn_buffer_begin_init(); |
kbd_type = KBD_SGCN; |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_SGCN); |
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (!t) |
panic("Cannot create kkbdpoll."); |
thread_ready(t); |
indev_initialize("sgcnin", &sgcnin, &sgcnin_ops); |
return &sgcnin; |
} |
/** |
* 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/network/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) |
{ |
95,11 → 93,12 |
ofw_upa_reg_t *reg = prop->value; |
count_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, ®[PCI_SABRE_REGS_REG], &paddr)) |
if (!ofw_upa_apply_ranges(node->parent, ®[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) |
{ |
135,11 → 140,12 |
ofw_upa_reg_t *reg = prop->value; |
count_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, ®[PCI_PSYCHO_REGS_REG], &paddr)) |
if (!ofw_upa_apply_ranges(node->parent, ®[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) |
{ |
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/network/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 |
282,15 → 298,32 |
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 |
/branches/network/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/network/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/network/kernel/arch/ia64/include/ski/ski.h |
---|
35,22 → 35,17 |
#ifndef KERN_ia64_SKI_H_ |
#define KERN_ia64_SKI_H_ |
#include <arch/types.h> |
#include <console/console.h> |
#include <console/chardev.h> |
#define SKI_INIT_CONSOLE 20 |
#define SKI_GETCHAR 21 |
#define SKI_PUTCHAR 31 |
extern chardev_t ski_uconsole; |
extern void ski_init_console(void); |
extern indev_t *skiin_init(void); |
extern void skiout_init(void); |
extern void ski_kbd_grab(void); |
extern void ski_kbd_release(void); |
extern void kkbdpoll(void *arg); |
#endif |
/** @} |
/branches/network/kernel/arch/ia64/include/types.h |
---|
65,6 → 65,11 |
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. */ |
/branches/network/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/network/kernel/arch/ia64/include/arch.h |
---|
39,6 → 39,8 |
#include <arch/ski/ski.h> |
extern void arch_pre_main(void); |
#endif |
/** @} |
/branches/network/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/network/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/network/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; |
*((uint8_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) |
*((uint16_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; |
*((uint32_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 *((uint8_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 *((uint16_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 *((uint32_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/network/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/network/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) |
/branches/network/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 { |
/branches/network/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/network/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/network/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/network/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/network/kernel/arch/ia64/include/drivers/i8042.h |
---|
File deleted |
/branches/network/kernel/arch/ia64/include/drivers/ega.h |
---|
File deleted |
/branches/network/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/network/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/network/kernel/arch/ia64/Makefile.inc |
---|
29,18 → 29,11 |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-little |
BFD_ARCH = ia64-elf64 |
TARGET = ia64-pc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64 |
INIT0_ADDRESS = 0xe000000004404000 |
INIT0_SIZE = 0x100000 |
CMN1 = -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127 |
GCC_CFLAGS += $(CMN1) |
ICC_CFLAGS += $(CMN1) |
48,58 → 41,35 |
LFLAGS += -EL |
AFLAGS += -mconstant-gp |
DEFS += -D__64_BITS__ -DINIT0_ADDRESS=$(INIT0_ADDRESS) -DINIT0_SIZE=$(INIT0_SIZE) -D$(MACHINE) |
DEFS += -D__64_BITS__ |
## 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 |
ARCH_SOURCES += arch/$(KARCH)/src/ski/ski.c |
DEFS += -DSKI |
# BFD = elf64-ia64-little |
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/network/kernel/arch/ia64/src/putchar.c |
---|
File deleted |
/branches/network/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/network/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/ski/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/network/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/network/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/network/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/network/kernel/arch/ia64/src/ia64.c |
---|
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; |
strncpy(init.tasks[i].name, bootinfo->taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
/* |
#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,55 |
{ |
} |
#ifdef I460GX |
#define POLL_INTERVAL 50000 /* 50 ms */ |
/** Kernel thread for polling keyboard. */ |
static void i8042_kkbdpoll(void *arg) |
{ |
while (1) { |
i8042_poll(); |
thread_usleep(POLL_INTERVAL); |
} |
} |
#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); |
indev_t *in; |
in = skiin_init(); |
if (in) |
srln_init(in); |
skiout_init(); |
#endif |
} |
#ifdef CONFIG_EGA |
ega_init(EGA_BASE, EGA_VIDEORAM); |
#endif |
#ifdef CONFIG_NS16550 |
indev_t *kbrdin_ns16550 |
= ns16550_init((ns16550_t *) NS16550_BASE, NS16550_IRQ, NULL, NULL); |
if (kbrdin_ns16550) |
srln_init(kbrdin_ns16550); |
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 |
indev_t *kbrdin_i8042 = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (kbrdin_i8042) |
kbrd_init(kbrdin_i8042); |
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 → 203,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. |
210,8 → 240,9 |
{ |
#ifdef SKI |
ski_kbd_grab(); |
#endif |
#endif |
} |
/** Return console to userspace |
* |
*/ |
224,9 → 255,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/network/kernel/arch/ia64/src/ski/ski.c |
---|
35,29 → 35,19 |
#include <arch/ski/ski.h> |
#include <console/console.h> |
#include <console/chardev.h> |
#include <arch/interrupt.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/types.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <ipc/irq.h> |
#include <proc/thread.h> |
#include <synch/spinlock.h> |
#include <arch/asm.h> |
#include <arch/drivers/kbd.h> |
#include <arch.h> |
#define SKI_KBD_INR 0 |
static indev_t skiin; /**< Ski input device. */ |
static outdev_t skiout; /**< Ski output device. */ |
static irq_t ski_kbd_irq; |
static devno_t ski_kbd_devno; |
chardev_t ski_console; |
chardev_t ski_uconsole; |
static bool kbd_disabled; |
static void ski_putchar(chardev_t *d, const char ch); |
static int32_t ski_getchar(void); |
/** Display character on debug console |
* |
* Use SSC (Simulator System Call) to |
66,21 → 56,31 |
* @param d Character device. |
* @param ch Character to be printed. |
*/ |
void ski_putchar(chardev_t *d, const char ch) |
static void ski_putchar(outdev_t *d, const char ch, bool silent) |
{ |
asm volatile ( |
"mov r15 = %0\n" |
"mov r32 = %1\n" /* r32 is in0 */ |
"break 0x80000\n" /* modifies r8 */ |
: |
: "i" (SKI_PUTCHAR), "r" (ch) |
: "r15", "in0", "r8" |
); |
if (ch == '\n') |
ski_putchar(d, '\r'); |
if (!silent) { |
asm volatile ( |
"mov r15 = %0\n" |
"mov r32 = %1\n" /* r32 is in0 */ |
"break 0x80000\n" /* modifies r8 */ |
: |
: "i" (SKI_PUTCHAR), "r" (ch) |
: "r15", "in0", "r8" |
); |
if (ch == '\n') |
ski_putchar(d, '\r', false); |
} |
} |
static indev_operations_t skiin_ops = { |
.poll = NULL |
}; |
static outdev_operations_t skiout_ops = { |
.write = ski_putchar |
}; |
/** Ask debug console if a key was pressed. |
* |
* Use SSC (Simulator System Call) to |
90,7 → 90,7 |
* |
* @return ASCII code of pressed key or 0 if no key pressed. |
*/ |
int32_t ski_getchar(void) |
static int32_t ski_getchar(void) |
{ |
uint64_t ch; |
107,102 → 107,47 |
return (int32_t) ch; |
} |
/** |
* This is a blocking wrapper for ski_getchar(). |
* To be used when the kernel crashes. |
*/ |
static char ski_getchar_blocking(chardev_t *d) |
{ |
int ch; |
while(!(ch = ski_getchar())) |
; |
if(ch == '\r') |
ch = '\n'; |
return (char) ch; |
} |
/** Ask keyboard if a key was pressed. */ |
static void poll_keyboard(void) |
{ |
char ch; |
static char last; |
ipl_t ipl; |
ipl = interrupts_disable(); |
if (kbd_disabled) { |
interrupts_restore(ipl); |
if (kbd_disabled) |
return; |
} |
spinlock_lock(&ski_kbd_irq.lock); |
ch = ski_getchar(); |
if(ch == '\r') |
ch = '\n'; |
if (ch) { |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
chardev_push_character(&ski_uconsole, ch); |
ipc_irq_send_notif(&ski_kbd_irq); |
} else { |
chardev_push_character(&ski_console, ch); |
} |
last = ch; |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
indev_push_character(&skiin, ch); |
return; |
} |
if (last) { |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
chardev_push_character(&ski_uconsole, 0); |
ipc_irq_send_notif(&ski_kbd_irq); |
} |
last = 0; |
} |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
} |
/* Called from getc(). */ |
static void ski_kbd_enable(chardev_t *d) |
{ |
kbd_disabled = false; |
} |
#define POLL_INTERVAL 10000 /* 10 ms */ |
/* Called from getc(). */ |
static void ski_kbd_disable(chardev_t *d) |
/** Kernel thread for polling keyboard. */ |
static void kkbdpoll(void *arg) |
{ |
kbd_disabled = true; |
while (1) { |
if (!silent) { |
poll_keyboard(); |
} |
thread_usleep(POLL_INTERVAL); |
} |
} |
/** Decline to service hardware IRQ. |
* |
* This is only a virtual IRQ, so always decline. |
* |
* @return Always IRQ_DECLINE. |
*/ |
static irq_ownership_t ski_kbd_claim(void) |
{ |
return IRQ_DECLINE; |
} |
static chardev_operations_t ski_ops = { |
.resume = ski_kbd_enable, |
.suspend = ski_kbd_disable, |
.write = ski_putchar, |
.read = ski_getchar_blocking |
}; |
/** Initialize debug console |
* |
* Issue SSC (Simulator System Call) to |
* to open debug console. |
*/ |
void ski_init_console(void) |
static void ski_init(void) |
{ |
static bool initialized; |
if (initialized) |
return; |
asm volatile ( |
"mov r15 = %0\n" |
"break 0x80000\n" |
210,54 → 155,46 |
: "i" (SKI_INIT_CONSOLE) |
: "r15", "r8" |
); |
initialized = true; |
} |
chardev_initialize("ski_console", &ski_console, &ski_ops); |
chardev_initialize("ski_uconsole", &ski_uconsole, &ski_ops); |
stdin = &ski_console; |
stdout = &ski_console; |
indev_t *skiin_init(void) |
{ |
ski_init(); |
ski_kbd_devno = device_assign_devno(); |
irq_initialize(&ski_kbd_irq); |
ski_kbd_irq.inr = SKI_KBD_INR; |
ski_kbd_irq.devno = ski_kbd_devno; |
ski_kbd_irq.claim = ski_kbd_claim; |
irq_register(&ski_kbd_irq); |
indev_initialize("skiin", &skiin, &skiin_ops); |
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (t) |
thread_ready(t); |
else |
return NULL; |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, SKI_KBD_INR); |
sysinfo_set_item_val("kbd.devno", NULL, ski_kbd_devno); |
sysinfo_set_item_val("kbd.type", NULL, KBD_SKI); |
return &skiin; |
} |
void ski_kbd_grab(void) |
void skiout_init(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&ski_kbd_irq.lock); |
ski_kbd_irq.notif_cfg.notify = false; |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
ski_init(); |
outdev_initialize("skiout", &skiout, &skiout_ops); |
stdout = &skiout; |
sysinfo_set_item_val("fb", NULL, false); |
} |
void ski_kbd_release(void) |
void ski_kbd_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&ski_kbd_irq.lock); |
if (ski_kbd_irq.notif_cfg.answerbox) |
ski_kbd_irq.notif_cfg.notify = true; |
spinlock_unlock(&ski_kbd_irq.lock); |
interrupts_restore(ipl); |
kbd_disabled = true; |
} |
#define POLL_INTERVAL 50000 /* 50 ms */ |
/** Kernel thread for polling keyboard. */ |
void kkbdpoll(void *arg) |
void ski_kbd_release(void) |
{ |
while (1) { |
poll_keyboard(); |
thread_usleep(POLL_INTERVAL); |
} |
kbd_disabled = false; |
} |
/** @} |
/branches/network/kernel/arch/ia64/src/cpu/cpu.c |
---|
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/network/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) |
{ |
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, index_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, index_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, |
index_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, |
index_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) |
{ |
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,10 → 702,9 |
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); |
678,11 → 743,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/network/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(); |
/branches/network/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/network/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/network/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,10 → 123,10 |
* |
* 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) |
{ |
166,10 → 167,11 |
* |
* 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) |
{ |
210,12 → 212,15 |
/** 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; |
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/network/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,8 |
#include <ipc/irq.h> |
#include <ipc/ipc.h> |
#include <synch/spinlock.h> |
#include <mm/tlb.h> |
#include <symtab.h> |
#define VECTORS_64_BUNDLE 20 |
#define VECTORS_16_BUNDLE 48 |
136,9 → 137,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 → 186,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 → 228,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/network/kernel/arch/ia64/src/drivers/ega.c |
---|
File deleted |
/branches/network/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/network/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/network/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/network/kernel/arch/arm32/include/machine.h |
---|
File deleted |
/branches/network/kernel/arch/arm32/include/boot.h |
---|
File deleted |
/branches/network/kernel/arch/arm32/include/debug/print.h |
---|
File deleted |
/branches/network/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/network/kernel/arch/arm32/include/interrupt.h |
---|
37,6 → 37,7 |
#define KERN_arm32_INTERRUPT_H_ |
#include <arch/types.h> |
#include <arch/exception.h> |
/** Initial size of exception dispatch table. */ |
#define IVT_ITEMS 6 |
/branches/network/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/network/kernel/arch/arm32/include/console.h |
---|
36,13 → 36,6 |
#ifndef KERN_arm32_CONSOLE_H_ |
#define KERN_arm32_CONSOLE_H_ |
/** Initializes console. |
* |
* @param devno Console device number. |
*/ |
extern void console_init(devno_t devno); |
#endif |
/** @} |
/branches/network/kernel/arch/arm32/include/types.h |
---|
64,6 → 64,9 |
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. */ |
/branches/network/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/network/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/network/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/network/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/network/kernel/arch/arm32/include/mm/page.h |
---|
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) |
); |
} |
/branches/network/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/network/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/network/kernel/arch/arm32/include/drivers/gxemul.h |
---|
38,41 → 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_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/network/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,62 → 35,28 |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm |
KERNEL_LOAD_ADDRESS = 0x80200000 |
# ifeq ($(MACHINE), gxemul_testarm) |
DMACHINE = MACHINE_GXEMUL_TESTARM |
# endif |
ATSIGN = % |
GCC_CFLAGS += -fno-zero-initialized-in-bss |
DEFS += -D__32_BITS__ -DKERNEL_LOAD_ADDRESS=$(KERNEL_LOAD_ADDRESS) -D$(DMACHINE) |
DEFS += -D__32_BITS__ |
# 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 |
## 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 |
# 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/console.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/network/kernel/arch/arm32/src/debug/print.c |
---|
File deleted |
/branches/network/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/network/kernel/arch/arm32/src/console.c |
---|
26,32 → 26,28 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
/** @file |
* @brief Console. |
*/ |
#include <console/console.h> |
#include <arch/console.h> |
#include <arch/machine.h> |
#include <genarch/fb/fb.h> |
void console_init(devno_t devno) |
{ |
machine_console_init(devno); |
} |
/** Acquire console back for kernel. */ |
void arch_grab_console(void) |
{ |
machine_grab_console(); |
#ifdef CONFIG_FB |
fb_redraw(); |
#endif |
} |
/** Return console to userspace. */ |
void arch_release_console(void) |
{ |
machine_release_console(); |
} |
/** @} |
/branches/network/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 <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; |
strncpy(init.tasks[i].name, bootinfo->tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
} |
/** 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 |
fb_init(machine_get_fb_address(), 640, 480, 1920, VISUAL_RGB_8_8_8); |
#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,23 |
*/ |
void arch_post_smp_init(void) |
{ |
#ifdef CONFIG_ARM_KBD |
/* |
* Initialize the msim/GXemul keyboard port. Then initialize the serial line |
* module and connect it to the msim/GXemul keyboard. Enable keyboard interrupts. |
*/ |
indev_t *kbrdin = dsrlnin_init((dsrlnin_t *) gxemul_kbd, GXEMUL_KBD_IRQ); |
if (kbrdin) |
srln_init(kbrdin); |
/* |
* 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 → 176,8 |
/** Halts CPU. */ |
void cpu_halt(void) |
{ |
machine_cpu_halt(); |
*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET)) |
= 0; |
} |
/** Reboot. */ |
156,9 → 184,22 |
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; |
} |
/** @} |
*/ |
/branches/network/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/network/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, count_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/network/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/network/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,11 → 44,12 |
/** 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); |
58,10 → 58,9 |
/** 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/network/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/network/kernel/arch/arm32/src/panic.S |
---|
31,5 → 31,5 |
.global panic_printf |
panic_printf: |
bl debug_printf |
bl printf |
bl cpu_halt |
/branches/network/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/network/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/network/kernel/arch/arm32/src/drivers/gxemul.c |
---|
33,361 → 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> |
/* 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 #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; |
} |
/** @} |
*/ |
/branches/network/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/network/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/network/kernel/arch/ppc32/include/asm/regname.h |
---|
211,15 → 211,19 |
#define dbat2l 541 |
#define dbat3u 542 |
#define dbat3l 543 |
#define tlbmiss 980 |
#define ptehi 981 |
#define ptelo 982 |
#define hid0 1008 |
/* MSR bits */ |
#define msr_ir (1 << 4) |
#define msr_dr (1 << 5) |
#define msr_dr (1 << 4) |
#define msr_ir (1 << 5) |
#define msr_pr (1 << 14) |
#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/network/kernel/arch/ppc32/include/exception.h |
---|
36,6 → 36,7 |
#define KERN_ppc32_EXCEPTION_H_ |
#include <arch/types.h> |
#include <arch/regutils.h> |
typedef struct { |
uint32_t r0; |
74,6 → 75,7 |
uint32_t lr; |
uint32_t ctr; |
uint32_t xer; |
uint32_t dar; |
uint32_t r12; |
uint32_t sp; |
} istate_t; |
84,11 → 86,10 |
} |
/** Return true if exception happened while in userspace */ |
#include <panic.h> |
static inline int istate_from_uspace(istate_t *istate) |
{ |
panic("istate_from_uspace not yet implemented"); |
return 0; |
/* true if privilege level PR (copied from MSR) == 1 */ |
return (istate->srr1 & MSR_PR) != 0; |
} |
static inline unative_t istate_get_pc(istate_t *istate) |
/branches/network/kernel/arch/ppc32/include/regutils.h |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2008 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 ppc32 |
* @{ |
*/ |
/** |
* @file |
* @brief Utilities for convenient manipulation with ppc32 registers. |
*/ |
#ifndef KERN_ppc32_REGUTILS_H_ |
#define KERN_ppc32_REGUTILS_H_ |
#define MSR_PR (1 << 14) |
#endif |
/** @} |
*/ |
/branches/network/kernel/arch/ppc32/include/types.h |
---|
57,6 → 57,9 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef struct { |
} fncptr_t; |
/**< Formats for uintptr_t, size_t, count_t and index_t */ |
#define PRIp "x" |
#define PRIs "u" |
84,11 → 87,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/network/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/network/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/network/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/network/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/network/kernel/arch/ppc32/include/mm/page.h |
---|
120,7 → 120,7 |
/* 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 |
134,13 → 134,13 |
{ |
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) |
147,8 → 147,9 |
{ |
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/network/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/network/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/network/kernel/arch/ppc32/include/drivers/cuda.h |
---|
38,10 → 38,8 |
#include <arch/types.h> |
#include <typedefs.h> |
extern void cuda_init(devno_t devno, uintptr_t base, size_t size); |
extern void cuda_init(uintptr_t base, size_t size); |
extern int cuda_get_scancode(void); |
extern void cuda_grab(void); |
extern void cuda_release(void); |
#endif |
/branches/network/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 |
45,44 → 41,22 |
DEFS += -D__32_BITS__ |
## 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/drivers/cuda.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/network/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/network/kernel/arch/ppc32/src/asm.S |
---|
66,9 → 66,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 → 131,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,8 → 197,8 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
lwz r12, 156(sp) |
lwz sp, 160(sp) |
rfi |
/branches/network/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/network/kernel/arch/ppc32/src/ppc32.c |
---|
42,24 → 42,27 |
#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 <macros.h> |
#include <string.h> |
#define IRQ_COUNT 64 |
#define IRQ_COUNT 64 |
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; |
strncpy(init.tasks[i].name, bootinfo.taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
} |
75,35 → 78,50 |
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); |
if (bootinfo.macio.addr) { |
/* Initialize PIC */ |
pic_init(bootinfo.macio.addr, PAGE_SIZE); |
/* Initialize I/O controller */ |
cuda_init(bootinfo.macio.addr + 0x16000, 2 * PAGE_SIZE); |
} |
/* Merge all zones to 1 big zone */ |
zone_merge_all(); |
128,11 → 146,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 → 160,9 |
*/ |
void arch_grab_console(void) |
{ |
cuda_grab(); |
#ifdef CONFIG_FB |
fb_redraw(); |
#endif |
} |
/** Return console to userspace |
148,8 → 170,21 |
*/ |
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; |
} |
/** @} |
*/ |
/branches/network/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) |
); |
} |
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/network/kernel/arch/ppc32/src/mm/frame.c |
---|
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/network/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/network/kernel/arch/ppc32/src/interrupt.c |
---|
73,7 → 73,7 |
ack = true; |
} |
irq->handler(irq, irq->arg); |
irq->handler(irq); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
92,8 → 92,8 |
static void exception_decrementer(int n, istate_t *istate) |
{ |
start_decrementer(); |
clock(); |
start_decrementer(); |
} |
/branches/network/kernel/arch/ppc32/src/drivers/pic.c |
---|
38,7 → 38,7 |
#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) |
{ |
47,10 → 47,11 |
void pic_enable_interrupt(int 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)); |
} |
} |
57,34 → 58,39 |
void pic_disable_interrupt(int 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) |
{ |
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/network/kernel/arch/ppc32/src/drivers/cuda.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32 |
/** @addtogroup ppc32 |
* @{ |
*/ |
/** @file |
33,7 → 33,6 |
*/ |
#include <arch/drivers/cuda.h> |
#include <ipc/irq.h> |
#include <arch/asm.h> |
#include <console/console.h> |
#include <console/chardev.h> |
41,6 → 40,7 |
#include <sysinfo/sysinfo.h> |
#include <interrupt.h> |
#include <stdarg.h> |
#include <ddi/device.h> |
#define CUDA_IRQ 10 |
#define SPECIAL '?' |
205,101 → 205,52 |
} |
/* Called from getc(). */ |
static void cuda_resume(chardev_t *d) |
{ |
} |
/* Called from getc(). */ |
static void cuda_suspend(chardev_t *d) |
{ |
} |
static char key_read(chardev_t *d) |
{ |
char ch; |
ch = 0; |
return ch; |
} |
static chardev_t kbrd; |
static chardev_operations_t ops = { |
.suspend = cuda_suspend, |
.resume = cuda_resume, |
.read = key_read |
static indev_t kbrd; |
static indev_operations_t ops = { |
.poll = NULL |
}; |
int cuda_get_scancode(void) |
{ |
uint8_t kind; |
uint8_t data[4]; |
if (cuda) { |
uint8_t kind; |
uint8_t data[4]; |
receive_packet(&kind, 4, data); |
if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c)) |
return data[2]; |
} |
receive_packet(&kind, 4, data); |
if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c)) |
return data[2]; |
return -1; |
} |
static void cuda_irq_handler(irq_t *irq, void *arg, ...) |
static void cuda_irq_handler(irq_t *irq) |
{ |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) |
ipc_irq_send_notif(irq); |
else { |
int scan_code = cuda_get_scancode(); |
if (scan_code != -1) { |
uint8_t scancode = (uint8_t) scan_code; |
if ((scancode & 0x80) != 0x80) |
chardev_push_character(&kbrd, lchars[scancode & 0x7f]); |
} |
int scan_code = cuda_get_scancode(); |
if (scan_code != -1) { |
uint8_t scancode = (uint8_t) scan_code; |
if ((scancode & 0x80) != 0x80) |
indev_push_character(&kbrd, lchars[scancode & 0x7f]); |
} |
} |
static irq_ownership_t cuda_claim(void) |
static irq_ownership_t cuda_claim(irq_t *irq) |
{ |
return IRQ_ACCEPT; |
} |
/** Initialize keyboard and service interrupts using kernel routine */ |
void cuda_grab(void) |
void cuda_init(uintptr_t base, size_t size) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&cuda_irq.lock); |
cuda_irq.notif_cfg.notify = false; |
spinlock_unlock(&cuda_irq.lock); |
interrupts_restore(ipl); |
} |
/** Resume the former interrupt vector */ |
void cuda_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&cuda_irq.lock); |
if (cuda_irq.notif_cfg.answerbox) |
cuda_irq.notif_cfg.notify = true; |
spinlock_unlock(&cuda_irq.unlock); |
interrupts_restore(ipl); |
} |
void cuda_init(devno_t devno, uintptr_t base, size_t size) |
{ |
cuda = (uint8_t *) hw_map(base, size); |
cuda = (uint8_t *) hw_map(base, size); |
chardev_initialize("cuda_kbd", &kbrd, &ops); |
indev_initialize("cuda_kbd", &kbrd, &ops); |
stdin = &kbrd; |
irq_initialize(&cuda_irq); |
cuda_irq.devno = devno; |
cuda_irq.devno = device_assign_devno(); |
cuda_irq.inr = CUDA_IRQ; |
cuda_irq.claim = cuda_claim; |
cuda_irq.handler = cuda_irq_handler; |
306,9 → 257,8 |
irq_register(&cuda_irq); |
pic_enable_interrupt(CUDA_IRQ); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, CUDA_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, base); |
} |
345,7 → 295,9 |
} |
void arch_reboot(void) { |
send_packet(PACKET_CUDA, 1, CUDA_RESET); |
if (cuda) |
send_packet(PACKET_CUDA, 1, CUDA_RESET); |
asm volatile ( |
"b 0\n" |
); |
/branches/network/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/network/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/network/kernel/arch/amd64/include/drivers/vesa.h |
---|
File deleted |
/branches/network/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/network/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/network/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/network/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 |
57,6 → 57,9 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef struct { |
} fncptr_t; |
/**< Formats for uintptr_t, size_t, count_t and index_t */ |
#define PRIp "llx" |
#define PRIs "llu" |
/branches/network/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/network/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,7 → 111,7 |
static inline void atomic_lock_arch(atomic_t *val) |
{ |
uint64_t tmp; |
preemption_disable(); |
asm volatile ( |
"0:\n" |
106,15 → 118,15 |
#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/network/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/network/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/network/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/network/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/network/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/network/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/network/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. */ |
count_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/network/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,50 |
ICC_CFLAGS += $(CMN1) |
SUNCC_CFLAGS += -m64 -xmodel=kernel |
DEFS += -DMACHINE=$(MACHINE) -D__64_BITS__ |
DEFS += -D__64_BITS__ |
## 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/network/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/network/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/network/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,28 |
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. |
*/ |
indev_t *kbrdin = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (kbrdin) { |
kbrd_init(kbrdin); |
trap_virtual_enable_irqs(1 << IRQ_KBD); |
} |
/* |
* This is the necessary evil until the userspace driver is entirely |
* self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
#endif |
} |
void calibrate_delay_loop(void) |
208,15 → 248,38 |
*/ |
void arch_grab_console(void) |
{ |
i8042_grab(); |
#ifdef CONFIG_FB |
if (vesa_present()) |
vesa_redraw(); |
else |
#endif |
#ifdef CONFIG_EGA |
ega_redraw(); |
#else |
{} |
#endif |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
i8042_release(); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
/** @} |
*/ |
/branches/network/kernel/arch/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); |
/* |
/branches/network/kernel/arch/amd64/src/ddi/ddi.c |
---|
57,15 → 57,15 |
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) |
{ |
count_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); |
/* |
* Increment I/O Permission bitmap generation counter. |
*/ |
task->arch.iomapver++; |
return 0; |
} |
122,7 → 122,7 |
descriptor_t *gdt_p; |
tss_descriptor_t *tss_desc; |
count_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/network/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/network/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/network/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/network/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/network/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/network/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/network/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/network/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/network/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/network/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/network/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. */ |
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/network/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/network/kernel/arch/mips32/include/boot.h |
---|
File deleted |
/branches/network/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 100 |
#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/network/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/network/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/network/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/network/kernel/arch/mips32/include/console.h |
---|
35,8 → 35,6 |
#ifndef KERN_mips32_CONSOLE_H_ |
#define KERN_mips32_CONSOLE_H_ |
extern void console_init(devno_t devno); |
#endif |
/** @} |
/branches/network/kernel/arch/mips32/include/types.h |
---|
57,6 → 57,9 |
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. */ |
/branches/network/kernel/arch/mips32/include/smp/order.h |
---|
File deleted |
/branches/network/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/network/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/network/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 count_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/network/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/network/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/network/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/network/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/network/kernel/arch/mips32/include/cpu.h |
---|
42,7 → 42,7 |
uint32_t imp_num; |
uint32_t rev_num; |
} cpu_arch_t; |
#endif |
/** @} |
/branches/network/kernel/arch/mips32/include/drivers/serial.h |
---|
File deleted |
/branches/network/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/network/kernel/arch/mips32/Makefile.inc |
---|
29,90 → 29,49 |
## 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 |
INIT_ADDRESS = 0x81000000 |
INIT_SIZE = 262144 |
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3 |
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss |
DEFS += -D__32_BITS__ |
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS} -DINIT_ADDRESS=${INIT_ADDRESS} -DINIT_SIZE=${INIT_SIZE} |
## 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 |
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 |
INIT_ADDRESS = 0x81800000 |
BFD_NAME = elf32-tradbigmips |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips |
TARGET = mips-linux-gnu |
GCC_CFLAGS += -DBIG_ENDIAN |
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 |
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/console.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/network/kernel/arch/mips32/src/drivers/msim.c |
---|
File deleted |
/branches/network/kernel/arch/mips32/src/drivers/serial.c |
---|
File deleted |
/branches/network/kernel/arch/mips32/src/dummy.S |
---|
File deleted |
/branches/network/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/network/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/network/kernel/arch/mips32/src/smp/order.c |
---|
File deleted |
/branches/network/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/network/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/network/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 |
66,235 → 71,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/network/kernel/arch/mips32/src/console.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
33,24 → 33,16 |
*/ |
#include <console/console.h> |
#include <arch/console.h> |
#include <arch/drivers/serial.h> |
#include <arch/drivers/msim.h> |
#include <genarch/fb/fb.h> |
void console_init(devno_t devno) |
{ |
if (serial_init()) |
serial_console(devno); |
else |
msim_console(devno); |
} |
/** Acquire console back for kernel |
* |
*/ |
void arch_grab_console(void) |
{ |
msim_kbd_grab(); |
#ifdef CONFIG_FB |
fb_redraw(); |
#endif |
} |
/** Return console to userspace |
58,7 → 50,6 |
*/ |
void arch_release_console(void) |
{ |
msim_kbd_release(); |
} |
/** @} |
/branches/network/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/network/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/network/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/network/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,22 → 40,21 |
#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 *istate); |
static void tlb_invalid_fail(istate_t *istate); |
static void tlb_modified_fail(istate_t *istate); |
static void tlb_refill_fail(istate_t *); |
static void tlb_invalid_fail(istate_t *); |
static void tlb_modified_fail(istate_t *); |
static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc); |
static pte_t *find_mapping_and_check(uintptr_t, int, istate_t *, int *); |
/** Initialize TLB |
/** Initialize TLB. |
* |
* Initialize TLB. |
* Invalidate all entries and mark wired entries. |
*/ |
void tlb_arch_init(void) |
81,11 → 80,9 |
cp0_wired_write(TLB_WIRED); |
} |
/** Process TLB Refill Exception |
/** Process TLB Refill Exception. |
* |
* Process TLB Refill Exception. |
* |
* @param istate Interrupted register context. |
* @param istate Interrupted register context. |
*/ |
void tlb_refill(istate_t *istate) |
{ |
95,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) { |
118,7 → 115,7 |
page_table_unlock(AS, true); |
return; |
default: |
panic("unexpected pfrc (%d)\n", pfrc); |
panic("Unexpected pfrc (%d).", pfrc); |
} |
} |
128,13 → 125,14 |
pte->a = 1; |
tlb_prepare_entry_hi(&hi, asid, badvaddr); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, |
pte->pfn); |
/* |
* New entry is to be inserted into TLB |
*/ |
cp0_entry_hi_write(hi.value); |
if ((badvaddr/PAGE_SIZE) % 2 == 0) { |
if ((badvaddr / PAGE_SIZE) % 2 == 0) { |
cp0_entry_lo0_write(lo.value); |
cp0_entry_lo1_write(0); |
} |
153,11 → 151,9 |
tlb_refill_fail(istate); |
} |
/** Process TLB Invalid Exception |
/** Process TLB Invalid Exception. |
* |
* Process TLB Invalid Exception. |
* |
* @param istate Interrupted register context. |
* @param istate Interrupted register context. |
*/ |
void tlb_invalid(istate_t *istate) |
{ |
203,7 → 199,7 |
page_table_unlock(AS, true); |
return; |
default: |
panic("unexpected pfrc (%d)\n", pfrc); |
panic("Unexpected pfrc (%d).", pfrc); |
} |
} |
217,12 → 213,13 |
*/ |
pte->a = 1; |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, |
pte->pfn); |
/* |
* The entry is to be updated in TLB. |
*/ |
if ((badvaddr/PAGE_SIZE) % 2 == 0) |
if ((badvaddr / PAGE_SIZE) % 2 == 0) |
cp0_entry_lo0_write(lo.value); |
else |
cp0_entry_lo1_write(lo.value); |
237,11 → 234,9 |
tlb_invalid_fail(istate); |
} |
/** Process TLB Modified Exception |
/** Process TLB Modified Exception. |
* |
* Process TLB Modified Exception. |
* |
* @param istate Interrupted register context. |
* @param istate Interrupted register context. |
*/ |
void tlb_modified(istate_t *istate) |
{ |
287,17 → 282,11 |
page_table_unlock(AS, true); |
return; |
default: |
panic("unexpected pfrc (%d)\n", pfrc); |
panic("Unexpected pfrc (%d).", pfrc); |
} |
} |
/* |
* Fail if the page is not writable. |
*/ |
if (!pte->w) |
goto fail; |
/* |
* Read the faulting TLB entry. |
*/ |
tlbr(); |
308,12 → 297,13 |
pte->a = 1; |
pte->d = 1; |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, |
pte->pfn); |
/* |
* The entry is to be updated in TLB. |
*/ |
if ((badvaddr/PAGE_SIZE) % 2 == 0) |
if ((badvaddr / PAGE_SIZE) % 2 == 0) |
cp0_entry_lo0_write(lo.value); |
else |
cp0_entry_lo1_write(lo.value); |
330,56 → 320,57 |
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", cp0_badvaddr_read()); |
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), istate->epc, symbol, sym2); |
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).", cp0_badvaddr_read(), |
istate->epc, symbol, sym2); |
} |
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", cp0_badvaddr_read()); |
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
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).", 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", cp0_badvaddr_read()); |
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
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).", cp0_badvaddr_read(), |
istate->epc, symbol); |
} |
/** Try to find PTE for faulting address |
/** Try to find PTE for faulting address. |
* |
* Try to find PTE for faulting address. |
* The AS->lock must be held on entry to this function. |
* |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code |
* will be stored. |
* |
* @return PTE on success, NULL otherwise. |
* @return PTE on success, NULL otherwise. |
*/ |
pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc) |
pte_t * |
find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, |
int *pfrc) |
{ |
entry_hi_t hi; |
pte_t *pte; |
398,7 → 389,7 |
* Check if the mapping exists in page tables. |
*/ |
pte = page_mapping_find(AS, badvaddr); |
if (pte && pte->p) { |
if (pte && pte->p && (pte->w || access != PF_ACCESS_WRITE)) { |
/* |
* Mapping found in page tables. |
* Immediately succeed. |
421,6 → 412,7 |
page_table_lock(AS, true); |
pte = page_mapping_find(AS, badvaddr); |
ASSERT(pte && pte->p); |
ASSERT(pte->w || access != PF_ACCESS_WRITE); |
return pte; |
break; |
case AS_PF_DEFER: |
430,18 → 422,19 |
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); |
} |
} |
} |
void tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn) |
void |
tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, |
uintptr_t pfn) |
{ |
lo->value = 0; |
lo->g = g; |
480,10 → 473,10 |
lo1.value = cp0_entry_lo1_read(); |
printf("%-2u %-4u %#6x %#4x %1u %1u %1u %1u %#6x\n", |
i, hi.asid, hi.vpn2, mask.mask, |
lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn); |
i, hi.asid, hi.vpn2, mask.mask, |
lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn); |
printf(" %1u %1u %1u %1u %#6x\n", |
lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn); |
lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn); |
} |
cp0_entry_hi_write(hi_save.value); |
560,11 → 553,12 |
cp0_entry_hi_write(hi_save.value); |
} |
/** Invalidate TLB entries for specified page range belonging to specified address space. |
/** Invalidate TLB entries for specified page range belonging to specified |
* address space. |
* |
* @param asid Address space identifier. |
* @param page First page whose TLB entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
* @param asid Address space identifier. |
* @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) |
{ |
588,7 → 582,10 |
index.value = cp0_index_read(); |
if (!index.p) { |
/* Entry was found, index register contains valid index. */ |
/* |
* Entry was found, index register contains valid |
* index. |
*/ |
tlbr(); |
lo0.value = cp0_entry_lo0_read(); |
/branches/network/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; |
65,7 → 65,6 |
static count_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))) |
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) |
/branches/network/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/network/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/network/kernel/arch/mips32/src/mips32.c |
---|
33,7 → 33,6 |
*/ |
#include <arch.h> |
#include <arch/boot.h> |
#include <arch/cp0.h> |
#include <arch/exception.h> |
#include <mm/as.h> |
53,39 → 52,52 |
#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) |
count_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; |
count_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; |
strncpy(init.tasks[i].name, bootinfo->tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
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 → 123,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 → 135,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 → 164,31 |
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. |
*/ |
indev_t *kbrdin = dsrlnin_init((dsrlnin_t *) MSIM_KBD_ADDRESS, MSIM_KBD_IRQ); |
if (kbrdin) { |
srln_init(kbrdin); |
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 → 199,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 → 231,22 |
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; |
} |
/** @} |
*/ |
/branches/network/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/network/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/network/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/network/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/network/kernel/arch/ia32/include/cpuid.h |
---|
74,21 → 74,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,7 → 98,8 |
{ |
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) |
); |
} |
/branches/network/kernel/arch/ia32/include/types.h |
---|
57,6 → 57,9 |
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. */ |
/branches/network/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/network/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,22 |
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 */ |
"pause\n" /* Pentium 4's HT love this instruction */ |
#endif |
"mov %0, %1\n" |
"testl %1, %1\n" |
"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/network/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/network/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/network/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/network/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/network/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/network/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/network/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/network/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/network/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/network/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. */ |
} cpu_arch_t; |
#endif |
#define CR4_OSFXSR_MASK (1<<9) |
#endif |
/** @} |
/branches/network/kernel/arch/ia32/include/drivers/i8042.h |
---|
File deleted |
/branches/network/kernel/arch/ia32/include/drivers/ega.h |
---|
File deleted |
/branches/network/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/network/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/network/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/network/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,7 |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686 |
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__ |
DEFS += -D__32_BITS__ |
CMN1 = -m32 |
GCC_CFLAGS += $(CMN1) |
49,115 → 45,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/network/kernel/arch/ia32/src/ia32.c |
---|
1,5 → 1,7 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2009 Jiri Svoboda |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
38,9 → 40,12 |
#include <arch/pm.h> |
#include <arch/drivers/ega.h> |
#include <genarch/multiboot/multiboot.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <genarch/drivers/ega/ega.h> |
#include <arch/drivers/vesa.h> |
#include <genarch/kbd/i8042.h> |
#include <genarch/drivers/i8042/i8042.h> |
#include <genarch/kbrd/kbrd.h> |
#include <arch/drivers/i8254.h> |
#include <arch/drivers/i8259.h> |
60,12 → 65,30 |
#include <proc/thread.h> |
#include <syscall/syscall.h> |
#include <console/console.h> |
#include <ddi/device.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/boot/boot.h> |
#ifdef CONFIG_SMP |
#include <arch/smp/apic.h> |
#endif |
/** Perform ia32-specific initialization before main_bsp() is called. |
* |
* @param signature Should contain the multiboot signature. |
* @param mi Pointer to the multiboot information structure. |
*/ |
void arch_pre_main(uint32_t signature, const multiboot_info_t *mi) |
{ |
/* Parse multiboot information obtained from the bootloader. */ |
multiboot_info_parse(signature, mi); |
#ifdef CONFIG_SMP |
/* Copy AP bootstrap routines below 1 MB. */ |
memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET, |
(size_t) &_hardcoded_unmapped_size); |
#endif |
} |
void arch_pre_mm_init(void) |
{ |
pm_init(); |
87,13 → 110,17 |
/* hard clock */ |
i8254_init(); |
#ifdef CONFIG_FB |
if (vesa_present()) |
if (vesa_present()) |
vesa_init(); |
else |
#endif |
ega_init(); /* video */ |
#ifdef CONFIG_EGA |
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */ |
#else |
{} |
#endif |
/* Enable debugger */ |
debugger_init(); |
123,10 → 150,28 |
void arch_post_smp_init(void) |
{ |
devno_t kbd = device_assign_devno(); |
devno_t mouse = device_assign_devno(); |
/* keyboard controller */ |
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE); |
#ifdef CONFIG_PC_KBD |
/* |
* Initialize the i8042 controller. Then initialize the keyboard |
* module and connect it to i8042. Enable keyboard interrupts. |
*/ |
indev_t *kbrdin = i8042_init((i8042_t *) I8042_BASE, IRQ_KBD); |
if (kbrdin) { |
kbrd_init(kbrdin); |
trap_virtual_enable_irqs(1 << IRQ_KBD); |
} |
/* |
* This is the necessary evil until the userspace driver is entirely |
* self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
#endif |
} |
void calibrate_delay_loop(void) |
159,15 → 204,38 |
*/ |
void arch_grab_console(void) |
{ |
i8042_grab(); |
#ifdef CONFIG_FB |
if (vesa_present()) |
vesa_redraw(); |
else |
#endif |
#ifdef CONFIG_EGA |
ega_redraw(); |
#else |
{} |
#endif |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
i8042_release(); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
/** @} |
*/ |
/branches/network/kernel/arch/ia32/src/fpu_context.c |
---|
44,46 → 44,43 |
static void fpu_context_f_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fnsave %0" |
: "=m"(*fctx) |
); |
"fnsave %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
static void fpu_context_f_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"frstor %0" |
: "=m"(*fctx) |
); |
"frstor %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
static void fpu_context_fx_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxsave %0" |
: "=m"(*fctx) |
); |
"fxsave %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
static void fpu_context_fx_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxrstor %0" |
: "=m"(*fctx) |
); |
"fxrstor %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
/* |
Setup using fxsr instruction |
*/ |
/* Setup using fxsr instruction */ |
void fpu_fxsr(void) |
{ |
fpu_save=fpu_context_fx_save; |
fpu_restore=fpu_context_fx_restore; |
} |
/* |
Setup using not fxsr instruction |
*/ |
/* Setup using not fxsr instruction */ |
void fpu_fsr(void) |
{ |
fpu_save = fpu_context_f_save; |
102,16 → 99,18 |
void fpu_init() |
{ |
uint32_t help0 = 0, help1 = 0; |
uint32_t help0 = 0; |
uint32_t help1 = 0; |
asm volatile ( |
"fninit;\n" |
"stmxcsr %0\n" |
"mov %0,%1;\n" |
"or %2,%1;\n" |
"mov %1,%0;\n" |
"ldmxcsr %0;\n" |
: "+m" (help0), "+r" (help1) |
: "i" (0x1f80) |
"fninit\n" |
"stmxcsr %[help0]\n" |
"mov %[help0], %[help1]\n" |
"or %[magic], %[help1]\n" |
"mov %[help1], %[help0]\n" |
"ldmxcsr %[help0]\n" |
: [help0] "+m" (help0), [help1] "+r" (help1) |
: [magic] "i" (0x1f80) |
); |
} |
/branches/network/kernel/arch/ia32/src/asm.S |
---|
147,6 → 147,46 |
popfl |
.endm |
/* |
* The SYSENTER syscall mechanism can be used for syscalls with |
* four or fewer arguments. To pass these four arguments, we |
* use four registers: EDX, ECX, EBX, ESI. The syscall number |
* is passed in EAX. We use EDI to remember the return address |
* and EBP to remember the stack. The INT-based syscall mechanism |
* can actually handle six arguments plus the syscall number |
* entirely in registers. |
*/ |
.global sysenter_handler |
sysenter_handler: |
sti |
pushl %ebp # remember user stack |
pushl %edi # remember return user address |
pushl %gs # remember TLS |
pushl %eax # syscall number |
subl $8, %esp # unused sixth and fifth argument |
pushl %esi # fourth argument |
pushl %ebx # third argument |
pushl %ecx # second argument |
pushl %edx # first argument |
movw $16, %ax |
movw %ax, %ds |
movw %ax, %es |
cld |
call syscall_handler |
addl $28, %esp # remove arguments from stack |
pop %gs # restore TLS |
pop %edx # prepare return EIP for SYSEXIT |
pop %ecx # prepare userspace ESP for SYSEXIT |
sysexit # return to userspace |
## Declare interrupt handlers |
# |
# Declare interrupt handlers for n interrupt |
228,14 → 268,6 |
pushl %fs |
pushl %gs |
#ifdef CONFIG_DEBUG_ALLREGS |
pushl %ebx |
pushl %ebp |
pushl %edi |
pushl %esi |
#else |
subl $16, %esp |
#endif |
pushl %edx |
pushl %ecx |
pushl %eax |
257,14 → 289,6 |
popl %eax |
popl %ecx |
popl %edx |
#ifdef CONFIG_DEBUG_ALLREGS |
popl %esi |
popl %edi |
popl %ebp |
popl %ebx |
#else |
addl $16, %esp |
#endif |
popl %gs |
popl %fs |
/branches/network/kernel/arch/ia32/src/cpu/cpu.c |
---|
42,22 → 42,23 |
#include <fpu_context.h> |
#include <arch/smp/apic.h> |
#include <arch/syscall.h> |
/* |
* Identification of CPUs. |
* Contains only non-MP-Specification specific SMP code. |
*/ |
#define AMD_CPUID_EBX 0x68747541 |
#define AMD_CPUID_ECX 0x444d4163 |
#define AMD_CPUID_EDX 0x69746e65 |
#define AMD_CPUID_EBX 0x68747541 |
#define AMD_CPUID_ECX 0x444d4163 |
#define AMD_CPUID_EDX 0x69746e65 |
#define INTEL_CPUID_EBX 0x756e6547 |
#define INTEL_CPUID_ECX 0x6c65746e |
#define INTEL_CPUID_EDX 0x49656e69 |
#define INTEL_CPUID_EBX 0x756e6547 |
#define INTEL_CPUID_ECX 0x6c65746e |
#define INTEL_CPUID_EDX 0x49656e69 |
enum vendor { |
VendorUnknown=0, |
VendorUnknown = 0, |
VendorAMD, |
VendorIntel |
}; |
64,19 → 65,17 |
static char *vendor_str[] = { |
"Unknown Vendor", |
"AuthenticAMD", |
"GenuineIntel" |
"AMD", |
"Intel" |
}; |
void fpu_disable(void) |
{ |
asm volatile ( |
"mov %%cr0,%%eax;" |
"or $8,%%eax;" |
"mov %%eax,%%cr0;" |
: |
: |
:"%eax" |
"mov %%cr0, %%eax\n" |
"or $8, %%eax\n" |
"mov %%eax, %%cr0\n" |
::: "%eax" |
); |
} |
83,13 → 82,11 |
void fpu_enable(void) |
{ |
asm volatile ( |
"mov %%cr0,%%eax;" |
"and $0xffFFffF7,%%eax;" |
"mov %%eax,%%cr0;" |
: |
: |
:"%eax" |
); |
"mov %%cr0, %%eax\n" |
"and $0xffFFffF7, %%eax\n" |
"mov %%eax,%%cr0\n" |
::: "%eax" |
); |
} |
void cpu_arch_init(void) |
101,11 → 98,11 |
CPU->arch.tss = tss_p; |
CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((uint8_t *) CPU->arch.tss); |
CPU->fpu_owner = NULL; |
cpuid(1, &info); |
fi.word = info.cpuid_edx; |
efi.word = info.cpuid_ecx; |
112,17 → 109,20 |
if (fi.bits.fxsr) |
fpu_fxsr(); |
else |
fpu_fsr(); |
fpu_fsr(); |
if (fi.bits.sse) { |
asm volatile ( |
"mov %%cr4,%0\n" |
"or %1,%0\n" |
"mov %0,%%cr4\n" |
: "+r" (help) |
: "i" (CR4_OSFXSR_MASK|(1<<10)) |
"mov %%cr4, %[help]\n" |
"or %[mask], %[help]\n" |
"mov %[help], %%cr4\n" |
: [help] "+r" (help) |
: [mask] "i" (CR4_OSFXSR_MASK | (1 << 10)) |
); |
} |
/* Setup fast SYSENTER/SYSEXIT syscalls */ |
syscall_setup_cpu(); |
} |
void cpu_identify(void) |
136,29 → 136,31 |
/* |
* Check for AMD processor. |
*/ |
if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) { |
if ((info.cpuid_ebx == AMD_CPUID_EBX) |
&& (info.cpuid_ecx == AMD_CPUID_ECX) |
&& (info.cpuid_edx == AMD_CPUID_EDX)) |
CPU->arch.vendor = VendorAMD; |
} |
/* |
* Check for Intel processor. |
*/ |
if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) { |
if ((info.cpuid_ebx == INTEL_CPUID_EBX) |
&& (info.cpuid_ecx == INTEL_CPUID_ECX) |
&& (info.cpuid_edx == INTEL_CPUID_EDX)) |
CPU->arch.vendor = VendorIntel; |
} |
cpuid(1, &info); |
CPU->arch.family = (info.cpuid_eax>>8)&0xf; |
CPU->arch.model = (info.cpuid_eax>>4)&0xf; |
CPU->arch.stepping = (info.cpuid_eax>>0)&0xf; |
CPU->arch.family = (info.cpuid_eax >> 8) & 0x0f; |
CPU->arch.model = (info.cpuid_eax >> 4) & 0x0f; |
CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0f; |
} |
} |
void cpu_print_report(cpu_t* m) |
void cpu_print_report(cpu_t* cpu) |
{ |
printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n", |
m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping, |
m->frequency_mhz); |
printf("cpu%u: (%s family=%u model=%u stepping=%u) %" PRIu16 " MHz\n", |
cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family, |
cpu->arch.model, cpu->arch.stepping, cpu->frequency_mhz); |
} |
/** @} |
/branches/network/kernel/arch/ia32/src/syscall.c |
---|
0,0 → 1,53 |
/* |
* Copyright (c) 2008 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/syscall.h> |
#include <arch/cpu.h> |
#include <arch/asm.h> |
#include <arch/types.h> |
#include <arch/pm.h> |
/** Enable & setup support for SYSENTER/SYSEXIT */ |
void syscall_setup_cpu(void) |
{ |
extern void sysenter_handler(void); |
/* set kernel mode CS selector */ |
write_msr(IA32_MSR_SYSENTER_CS, gdtselector(KTEXT_DES)); |
/* set kernel mode entry point */ |
write_msr(IA32_MSR_SYSENTER_EIP, (uint32_t) sysenter_handler); |
} |
/** @} |
*/ |
/branches/network/kernel/arch/ia32/src/pm.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
112,7 → 112,7 |
void tss_initialize(tss_t *t) |
{ |
memsetb(t, sizeof(struct tss), 0); |
memsetb(t, sizeof(tss_t), 0); |
} |
/* |
127,7 → 127,7 |
d = &idt[i]; |
d->unused = 0; |
d->selector = selector(KTEXT_DES); |
d->selector = gdtselector(KTEXT_DES); |
d->access = AR_PRESENT | AR_INTERRUPT; /* masking interrupt */ |
154,7 → 154,7 |
"and $0xffff8fff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
: : : "eax" |
::: "eax" |
); |
} |
165,7 → 165,7 |
"mov %%cr0, %%eax\n" |
"and $0xfffbffff, %%eax\n" |
"mov %%eax, %%cr0\n" |
: : : "eax" |
::: "eax" |
); |
} |
198,7 → 198,7 |
else { |
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC); |
if (!tss_p) |
panic("could not allocate TSS\n"); |
panic("Cannot allocate TSS."); |
} |
tss_initialize(tss_p); |
214,7 → 214,7 |
* As of this moment, the current CPU has its own GDT pointing |
* to its own TSS. We just need to load the TR register. |
*/ |
tr_load(selector(TSS_DES)); |
tr_load(gdtselector(TSS_DES)); |
clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels and clear NT flag. */ |
clean_AM_flag(); /* Disable alignment check */ |
/branches/network/kernel/arch/ia32/src/smp/smp.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
75,12 → 75,12 |
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, |
FRAME_ATOMIC | FRAME_KA); |
if (!l_apic_address) |
panic("cannot allocate address for l_apic\n"); |
panic("Cannot allocate address for l_apic."); |
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, |
FRAME_ATOMIC | FRAME_KA); |
if (!io_apic_address) |
panic("cannot allocate address for io_apic\n"); |
panic("Cannot allocate address for io_apic."); |
if (config.cpu_count > 1) { |
page_mapping_insert(AS_KERNEL, l_apic_address, |
122,8 → 122,8 |
* Save 0xa to address 0xf of the CMOS RAM. |
* BIOS will not do the POST after the INIT signal. |
*/ |
outb(0x70, 0xf); |
outb(0x71, 0xa); |
pio_write_8((ioport8_t *)0x70, 0xf); |
pio_write_8((ioport8_t *)0x71, 0xa); |
pic_disable_irqs(0xffff); |
apic_init(); |
131,8 → 131,8 |
uint8_t apic = l_apic_id(); |
for (i = 0; i < ops->cpu_count(); i++) { |
struct descriptor *gdt_new; |
descriptor_t *gdt_new; |
/* |
* Skip processors marked unusable. |
*/ |
154,14 → 154,19 |
/* |
* Prepare new GDT for CPU in question. |
*/ |
gdt_new = (struct descriptor *) malloc(GDT_ITEMS * |
sizeof(struct descriptor), FRAME_ATOMIC | FRAME_LOW_4_GiB); |
/* XXX Flag FRAME_LOW_4_GiB was removed temporarily, |
* it needs to be replaced by a generic fuctionality of |
* the memory subsystem |
*/ |
gdt_new = (descriptor_t *) malloc(GDT_ITEMS * |
sizeof(descriptor_t), FRAME_ATOMIC); |
if (!gdt_new) |
panic("couldn't allocate memory for GDT\n"); |
panic("Cannot allocate memory for GDT."); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor)); |
memsetb(&gdt_new[TSS_DES], sizeof(struct descriptor), 0); |
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t)); |
memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0); |
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(descriptor_t); |
protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new); |
gdtr.base = (uintptr_t) gdt_new; |
/branches/network/kernel/arch/ia32/src/smp/apic.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
132,12 → 132,12 |
#endif |
} |
static irq_ownership_t l_apic_timer_claim(void) |
static irq_ownership_t l_apic_timer_claim(irq_t *irq) |
{ |
return IRQ_ACCEPT; |
} |
static void l_apic_timer_irq_handler(irq_t *irq, void *arg __attribute__((unused)), ...) |
static void l_apic_timer_irq_handler(irq_t *irq) |
{ |
/* |
* Holding a spinlock could prevent clock() from preempting |
/branches/network/kernel/arch/ia32/src/ddi/ddi.c |
---|
156,7 → 156,7 |
* type must be changed to describe inactive TSS. |
*/ |
gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL; |
tr_load(selector(TSS_DES)); |
tr_load(gdtselector(TSS_DES)); |
/* |
* Update the generation count so that faults caused by |
/branches/network/kernel/arch/ia32/src/boot/vga323.pal |
---|
1,256 → 1,256 |
.byte 0x3f, 0x3f, 0x3f, 0x00 |
.byte 0x36, 0x3f, 0x3f, 0x00 |
.byte 0x2d, 0x3f, 0x3f, 0x00 |
.byte 0x24, 0x3f, 0x3f, 0x00 |
.byte 0x1b, 0x3f, 0x3f, 0x00 |
.byte 0x12, 0x3f, 0x3f, 0x00 |
.byte 0x09, 0x3f, 0x3f, 0x00 |
.byte 0x00, 0x3f, 0x3f, 0x00 |
.byte 0x3f, 0x2a, 0x3f, 0x00 |
.byte 0x36, 0x2a, 0x3f, 0x00 |
.byte 0x2d, 0x2a, 0x3f, 0x00 |
.byte 0x24, 0x2a, 0x3f, 0x00 |
.byte 0x1b, 0x2a, 0x3f, 0x00 |
.byte 0x12, 0x2a, 0x3f, 0x00 |
.byte 0x09, 0x2a, 0x3f, 0x00 |
.byte 0x00, 0x2a, 0x3f, 0x00 |
.byte 0x3f, 0x15, 0x3f, 0x00 |
.byte 0x36, 0x15, 0x3f, 0x00 |
.byte 0x2d, 0x15, 0x3f, 0x00 |
.byte 0x24, 0x15, 0x3f, 0x00 |
.byte 0x1b, 0x15, 0x3f, 0x00 |
.byte 0x12, 0x15, 0x3f, 0x00 |
.byte 0x09, 0x15, 0x3f, 0x00 |
.byte 0x00, 0x15, 0x3f, 0x00 |
.byte 0x3f, 0x00, 0x3f, 0x00 |
.byte 0x36, 0x00, 0x3f, 0x00 |
.byte 0x2d, 0x00, 0x3f, 0x00 |
.byte 0x24, 0x00, 0x3f, 0x00 |
.byte 0x1b, 0x00, 0x3f, 0x00 |
.byte 0x12, 0x00, 0x3f, 0x00 |
.byte 0x09, 0x00, 0x3f, 0x00 |
.byte 0x00, 0x00, 0x3f, 0x00 |
.byte 0x3f, 0x3f, 0x36, 0x00 |
.byte 0x36, 0x3f, 0x36, 0x00 |
.byte 0x2d, 0x3f, 0x36, 0x00 |
.byte 0x24, 0x3f, 0x36, 0x00 |
.byte 0x1b, 0x3f, 0x36, 0x00 |
.byte 0x12, 0x3f, 0x36, 0x00 |
.byte 0x09, 0x3f, 0x36, 0x00 |
.byte 0x00, 0x3f, 0x36, 0x00 |
.byte 0x3f, 0x2a, 0x36, 0x00 |
.byte 0x36, 0x2a, 0x36, 0x00 |
.byte 0x2d, 0x2a, 0x36, 0x00 |
.byte 0x24, 0x2a, 0x36, 0x00 |
.byte 0x1b, 0x2a, 0x36, 0x00 |
.byte 0x12, 0x2a, 0x36, 0x00 |
.byte 0x09, 0x2a, 0x36, 0x00 |
.byte 0x00, 0x2a, 0x36, 0x00 |
.byte 0x3f, 0x15, 0x36, 0x00 |
.byte 0x36, 0x15, 0x36, 0x00 |
.byte 0x2d, 0x15, 0x36, 0x00 |
.byte 0x24, 0x15, 0x36, 0x00 |
.byte 0x1b, 0x15, 0x36, 0x00 |
.byte 0x12, 0x15, 0x36, 0x00 |
.byte 0x09, 0x15, 0x36, 0x00 |
.byte 0x00, 0x15, 0x36, 0x00 |
.byte 0x3f, 0x00, 0x36, 0x00 |
.byte 0x36, 0x00, 0x36, 0x00 |
.byte 0x2d, 0x00, 0x36, 0x00 |
.byte 0x24, 0x00, 0x36, 0x00 |
.byte 0x1b, 0x00, 0x36, 0x00 |
.byte 0x12, 0x00, 0x36, 0x00 |
.byte 0x09, 0x00, 0x36, 0x00 |
.byte 0x00, 0x00, 0x36, 0x00 |
.byte 0x3f, 0x3f, 0x2d, 0x00 |
.byte 0x36, 0x3f, 0x2d, 0x00 |
.byte 0x2d, 0x3f, 0x2d, 0x00 |
.byte 0x24, 0x3f, 0x2d, 0x00 |
.byte 0x1b, 0x3f, 0x2d, 0x00 |
.byte 0x12, 0x3f, 0x2d, 0x00 |
.byte 0x09, 0x3f, 0x2d, 0x00 |
.byte 0x00, 0x3f, 0x2d, 0x00 |
.byte 0x3f, 0x2a, 0x2d, 0x00 |
.byte 0x36, 0x2a, 0x2d, 0x00 |
.byte 0x2d, 0x2a, 0x2d, 0x00 |
.byte 0x24, 0x2a, 0x2d, 0x00 |
.byte 0x1b, 0x2a, 0x2d, 0x00 |
.byte 0x12, 0x2a, 0x2d, 0x00 |
.byte 0x09, 0x2a, 0x2d, 0x00 |
.byte 0x00, 0x2a, 0x2d, 0x00 |
.byte 0x3f, 0x15, 0x2d, 0x00 |
.byte 0x36, 0x15, 0x2d, 0x00 |
.byte 0x2d, 0x15, 0x2d, 0x00 |
.byte 0x24, 0x15, 0x2d, 0x00 |
.byte 0x1b, 0x15, 0x2d, 0x00 |
.byte 0x12, 0x15, 0x2d, 0x00 |
.byte 0x09, 0x15, 0x2d, 0x00 |
.byte 0x00, 0x15, 0x2d, 0x00 |
.byte 0x3f, 0x00, 0x2d, 0x00 |
.byte 0x36, 0x00, 0x2d, 0x00 |
.byte 0x2d, 0x00, 0x2d, 0x00 |
.byte 0x24, 0x00, 0x2d, 0x00 |
.byte 0x1b, 0x00, 0x2d, 0x00 |
.byte 0x12, 0x00, 0x2d, 0x00 |
.byte 0x09, 0x00, 0x2d, 0x00 |
.byte 0x00, 0x00, 0x2d, 0x00 |
.byte 0x3f, 0x3f, 0x24, 0x00 |
.byte 0x36, 0x3f, 0x24, 0x00 |
.byte 0x2d, 0x3f, 0x24, 0x00 |
.byte 0x24, 0x3f, 0x24, 0x00 |
.byte 0x1b, 0x3f, 0x24, 0x00 |
.byte 0x12, 0x3f, 0x24, 0x00 |
.byte 0x09, 0x3f, 0x24, 0x00 |
.byte 0x00, 0x3f, 0x24, 0x00 |
.byte 0x3f, 0x2a, 0x24, 0x00 |
.byte 0x36, 0x2a, 0x24, 0x00 |
.byte 0x2d, 0x2a, 0x24, 0x00 |
.byte 0x24, 0x2a, 0x24, 0x00 |
.byte 0x1b, 0x2a, 0x24, 0x00 |
.byte 0x12, 0x2a, 0x24, 0x00 |
.byte 0x09, 0x2a, 0x24, 0x00 |
.byte 0x00, 0x2a, 0x24, 0x00 |
.byte 0x3f, 0x15, 0x24, 0x00 |
.byte 0x36, 0x15, 0x24, 0x00 |
.byte 0x2d, 0x15, 0x24, 0x00 |
.byte 0x24, 0x15, 0x24, 0x00 |
.byte 0x1b, 0x15, 0x24, 0x00 |
.byte 0x12, 0x15, 0x24, 0x00 |
.byte 0x09, 0x15, 0x24, 0x00 |
.byte 0x00, 0x15, 0x24, 0x00 |
.byte 0x3f, 0x00, 0x24, 0x00 |
.byte 0x36, 0x00, 0x24, 0x00 |
.byte 0x2d, 0x00, 0x24, 0x00 |
.byte 0x24, 0x00, 0x24, 0x00 |
.byte 0x1b, 0x00, 0x24, 0x00 |
.byte 0x12, 0x00, 0x24, 0x00 |
.byte 0x09, 0x00, 0x24, 0x00 |
.byte 0x00, 0x00, 0x24, 0x00 |
.byte 0x3f, 0x3f, 0x1b, 0x00 |
.byte 0x36, 0x3f, 0x1b, 0x00 |
.byte 0x2d, 0x3f, 0x1b, 0x00 |
.byte 0x24, 0x3f, 0x1b, 0x00 |
.byte 0x1b, 0x3f, 0x1b, 0x00 |
.byte 0x12, 0x3f, 0x1b, 0x00 |
.byte 0x09, 0x3f, 0x1b, 0x00 |
.byte 0x00, 0x3f, 0x1b, 0x00 |
.byte 0x3f, 0x2a, 0x1b, 0x00 |
.byte 0x36, 0x2a, 0x1b, 0x00 |
.byte 0x2d, 0x2a, 0x1b, 0x00 |
.byte 0x24, 0x2a, 0x1b, 0x00 |
.byte 0x1b, 0x2a, 0x1b, 0x00 |
.byte 0x12, 0x2a, 0x1b, 0x00 |
.byte 0x09, 0x2a, 0x1b, 0x00 |
.byte 0x00, 0x2a, 0x1b, 0x00 |
.byte 0x3f, 0x15, 0x1b, 0x00 |
.byte 0x36, 0x15, 0x1b, 0x00 |
.byte 0x2d, 0x15, 0x1b, 0x00 |
.byte 0x24, 0x15, 0x1b, 0x00 |
.byte 0x1b, 0x15, 0x1b, 0x00 |
.byte 0x12, 0x15, 0x1b, 0x00 |
.byte 0x09, 0x15, 0x1b, 0x00 |
.byte 0x00, 0x15, 0x1b, 0x00 |
.byte 0x3f, 0x00, 0x1b, 0x00 |
.byte 0x36, 0x00, 0x1b, 0x00 |
.byte 0x2d, 0x00, 0x1b, 0x00 |
.byte 0x24, 0x00, 0x1b, 0x00 |
.byte 0x1b, 0x00, 0x1b, 0x00 |
.byte 0x12, 0x00, 0x1b, 0x00 |
.byte 0x09, 0x00, 0x1b, 0x00 |
.byte 0x00, 0x00, 0x1b, 0x00 |
.byte 0x3f, 0x3f, 0x12, 0x00 |
.byte 0x36, 0x3f, 0x12, 0x00 |
.byte 0x2d, 0x3f, 0x12, 0x00 |
.byte 0x24, 0x3f, 0x12, 0x00 |
.byte 0x1b, 0x3f, 0x12, 0x00 |
.byte 0x12, 0x3f, 0x12, 0x00 |
.byte 0x09, 0x3f, 0x12, 0x00 |
.byte 0x00, 0x3f, 0x12, 0x00 |
.byte 0x3f, 0x2a, 0x12, 0x00 |
.byte 0x36, 0x2a, 0x12, 0x00 |
.byte 0x2d, 0x2a, 0x12, 0x00 |
.byte 0x24, 0x2a, 0x12, 0x00 |
.byte 0x1b, 0x2a, 0x12, 0x00 |
.byte 0x12, 0x2a, 0x12, 0x00 |
.byte 0x09, 0x2a, 0x12, 0x00 |
.byte 0x00, 0x2a, 0x12, 0x00 |
.byte 0x3f, 0x15, 0x12, 0x00 |
.byte 0x36, 0x15, 0x12, 0x00 |
.byte 0x2d, 0x15, 0x12, 0x00 |
.byte 0x24, 0x15, 0x12, 0x00 |
.byte 0x1b, 0x15, 0x12, 0x00 |
.byte 0x12, 0x15, 0x12, 0x00 |
.byte 0x09, 0x15, 0x12, 0x00 |
.byte 0x00, 0x15, 0x12, 0x00 |
.byte 0x3f, 0x00, 0x12, 0x00 |
.byte 0x36, 0x00, 0x12, 0x00 |
.byte 0x2d, 0x00, 0x12, 0x00 |
.byte 0x24, 0x00, 0x12, 0x00 |
.byte 0x1b, 0x00, 0x12, 0x00 |
.byte 0x12, 0x00, 0x12, 0x00 |
.byte 0x09, 0x00, 0x12, 0x00 |
.byte 0x00, 0x00, 0x12, 0x00 |
.byte 0x3f, 0x3f, 0x09, 0x00 |
.byte 0x36, 0x3f, 0x09, 0x00 |
.byte 0x2d, 0x3f, 0x09, 0x00 |
.byte 0x24, 0x3f, 0x09, 0x00 |
.byte 0x1b, 0x3f, 0x09, 0x00 |
.byte 0x12, 0x3f, 0x09, 0x00 |
.byte 0x09, 0x3f, 0x09, 0x00 |
.byte 0x00, 0x3f, 0x09, 0x00 |
.byte 0x3f, 0x2a, 0x09, 0x00 |
.byte 0x36, 0x2a, 0x09, 0x00 |
.byte 0x2d, 0x2a, 0x09, 0x00 |
.byte 0x24, 0x2a, 0x09, 0x00 |
.byte 0x1b, 0x2a, 0x09, 0x00 |
.byte 0x12, 0x2a, 0x09, 0x00 |
.byte 0x09, 0x2a, 0x09, 0x00 |
.byte 0x00, 0x2a, 0x09, 0x00 |
.byte 0x3f, 0x15, 0x09, 0x00 |
.byte 0x36, 0x15, 0x09, 0x00 |
.byte 0x2d, 0x15, 0x09, 0x00 |
.byte 0x24, 0x15, 0x09, 0x00 |
.byte 0x1b, 0x15, 0x09, 0x00 |
.byte 0x12, 0x15, 0x09, 0x00 |
.byte 0x09, 0x15, 0x09, 0x00 |
.byte 0x00, 0x15, 0x09, 0x00 |
.byte 0x3f, 0x00, 0x09, 0x00 |
.byte 0x36, 0x00, 0x09, 0x00 |
.byte 0x2d, 0x00, 0x09, 0x00 |
.byte 0x24, 0x00, 0x09, 0x00 |
.byte 0x1b, 0x00, 0x09, 0x00 |
.byte 0x12, 0x00, 0x09, 0x00 |
.byte 0x09, 0x00, 0x09, 0x00 |
.byte 0x00, 0x00, 0x09, 0x00 |
.byte 0x3f, 0x3f, 0x00, 0x00 |
.byte 0x36, 0x3f, 0x00, 0x00 |
.byte 0x2d, 0x3f, 0x00, 0x00 |
.byte 0x24, 0x3f, 0x00, 0x00 |
.byte 0x1b, 0x3f, 0x00, 0x00 |
.byte 0x12, 0x3f, 0x00, 0x00 |
.byte 0x09, 0x3f, 0x00, 0x00 |
.byte 0x00, 0x3f, 0x00, 0x00 |
.byte 0x3f, 0x2a, 0x00, 0x00 |
.byte 0x36, 0x2a, 0x00, 0x00 |
.byte 0x2d, 0x2a, 0x00, 0x00 |
.byte 0x24, 0x2a, 0x00, 0x00 |
.byte 0x1b, 0x2a, 0x00, 0x00 |
.byte 0x12, 0x2a, 0x00, 0x00 |
.byte 0x09, 0x2a, 0x00, 0x00 |
.byte 0x00, 0x2a, 0x00, 0x00 |
.byte 0x3f, 0x15, 0x00, 0x00 |
.byte 0x36, 0x15, 0x00, 0x00 |
.byte 0x2d, 0x15, 0x00, 0x00 |
.byte 0x24, 0x15, 0x00, 0x00 |
.byte 0x1b, 0x15, 0x00, 0x00 |
.byte 0x12, 0x15, 0x00, 0x00 |
.byte 0x09, 0x15, 0x00, 0x00 |
.byte 0x00, 0x15, 0x00, 0x00 |
.byte 0x3f, 0x00, 0x00, 0x00 |
.byte 0x36, 0x00, 0x00, 0x00 |
.byte 0x2d, 0x00, 0x00, 0x00 |
.byte 0x24, 0x00, 0x00, 0x00 |
.byte 0x1b, 0x00, 0x00, 0x00 |
.byte 0x12, 0x00, 0x00, 0x00 |
.byte 0x09, 0x00, 0x00, 0x00 |
.byte 0x00, 0x00, 0x00, 0x00 |
.byte 0x09, 0x00, 0x00, 0x00 |
.byte 0x12, 0x00, 0x00, 0x00 |
.byte 0x1b, 0x00, 0x00, 0x00 |
.byte 0x24, 0x00, 0x00, 0x00 |
.byte 0x2d, 0x00, 0x00, 0x00 |
.byte 0x36, 0x00, 0x00, 0x00 |
.byte 0x3f, 0x00, 0x00, 0x00 |
.byte 0x00, 0x15, 0x00, 0x00 |
.byte 0x09, 0x15, 0x00, 0x00 |
.byte 0x12, 0x15, 0x00, 0x00 |
.byte 0x1b, 0x15, 0x00, 0x00 |
.byte 0x24, 0x15, 0x00, 0x00 |
.byte 0x2d, 0x15, 0x00, 0x00 |
.byte 0x36, 0x15, 0x00, 0x00 |
.byte 0x3f, 0x15, 0x00, 0x00 |
.byte 0x00, 0x2a, 0x00, 0x00 |
.byte 0x09, 0x2a, 0x00, 0x00 |
.byte 0x12, 0x2a, 0x00, 0x00 |
.byte 0x1b, 0x2a, 0x00, 0x00 |
.byte 0x24, 0x2a, 0x00, 0x00 |
.byte 0x2d, 0x2a, 0x00, 0x00 |
.byte 0x36, 0x2a, 0x00, 0x00 |
.byte 0x3f, 0x2a, 0x00, 0x00 |
.byte 0x00, 0x3f, 0x00, 0x00 |
.byte 0x09, 0x3f, 0x00, 0x00 |
.byte 0x12, 0x3f, 0x00, 0x00 |
.byte 0x1b, 0x3f, 0x00, 0x00 |
.byte 0x24, 0x3f, 0x00, 0x00 |
.byte 0x2d, 0x3f, 0x00, 0x00 |
.byte 0x36, 0x3f, 0x00, 0x00 |
.byte 0x3f, 0x3f, 0x00, 0x00 |
.byte 0x00, 0x00, 0x09, 0x00 |
.byte 0x09, 0x00, 0x09, 0x00 |
.byte 0x12, 0x00, 0x09, 0x00 |
.byte 0x1b, 0x00, 0x09, 0x00 |
.byte 0x24, 0x00, 0x09, 0x00 |
.byte 0x2d, 0x00, 0x09, 0x00 |
.byte 0x36, 0x00, 0x09, 0x00 |
.byte 0x3f, 0x00, 0x09, 0x00 |
.byte 0x00, 0x15, 0x09, 0x00 |
.byte 0x09, 0x15, 0x09, 0x00 |
.byte 0x12, 0x15, 0x09, 0x00 |
.byte 0x1b, 0x15, 0x09, 0x00 |
.byte 0x24, 0x15, 0x09, 0x00 |
.byte 0x2d, 0x15, 0x09, 0x00 |
.byte 0x36, 0x15, 0x09, 0x00 |
.byte 0x3f, 0x15, 0x09, 0x00 |
.byte 0x00, 0x2a, 0x09, 0x00 |
.byte 0x09, 0x2a, 0x09, 0x00 |
.byte 0x12, 0x2a, 0x09, 0x00 |
.byte 0x1b, 0x2a, 0x09, 0x00 |
.byte 0x24, 0x2a, 0x09, 0x00 |
.byte 0x2d, 0x2a, 0x09, 0x00 |
.byte 0x36, 0x2a, 0x09, 0x00 |
.byte 0x3f, 0x2a, 0x09, 0x00 |
.byte 0x00, 0x3f, 0x09, 0x00 |
.byte 0x09, 0x3f, 0x09, 0x00 |
.byte 0x12, 0x3f, 0x09, 0x00 |
.byte 0x1b, 0x3f, 0x09, 0x00 |
.byte 0x24, 0x3f, 0x09, 0x00 |
.byte 0x2d, 0x3f, 0x09, 0x00 |
.byte 0x36, 0x3f, 0x09, 0x00 |
.byte 0x3f, 0x3f, 0x09, 0x00 |
.byte 0x00, 0x00, 0x12, 0x00 |
.byte 0x09, 0x00, 0x12, 0x00 |
.byte 0x12, 0x00, 0x12, 0x00 |
.byte 0x1b, 0x00, 0x12, 0x00 |
.byte 0x24, 0x00, 0x12, 0x00 |
.byte 0x2d, 0x00, 0x12, 0x00 |
.byte 0x36, 0x00, 0x12, 0x00 |
.byte 0x3f, 0x00, 0x12, 0x00 |
.byte 0x00, 0x15, 0x12, 0x00 |
.byte 0x09, 0x15, 0x12, 0x00 |
.byte 0x12, 0x15, 0x12, 0x00 |
.byte 0x1b, 0x15, 0x12, 0x00 |
.byte 0x24, 0x15, 0x12, 0x00 |
.byte 0x2d, 0x15, 0x12, 0x00 |
.byte 0x36, 0x15, 0x12, 0x00 |
.byte 0x3f, 0x15, 0x12, 0x00 |
.byte 0x00, 0x2a, 0x12, 0x00 |
.byte 0x09, 0x2a, 0x12, 0x00 |
.byte 0x12, 0x2a, 0x12, 0x00 |
.byte 0x1b, 0x2a, 0x12, 0x00 |
.byte 0x24, 0x2a, 0x12, 0x00 |
.byte 0x2d, 0x2a, 0x12, 0x00 |
.byte 0x36, 0x2a, 0x12, 0x00 |
.byte 0x3f, 0x2a, 0x12, 0x00 |
.byte 0x00, 0x3f, 0x12, 0x00 |
.byte 0x09, 0x3f, 0x12, 0x00 |
.byte 0x12, 0x3f, 0x12, 0x00 |
.byte 0x1b, 0x3f, 0x12, 0x00 |
.byte 0x24, 0x3f, 0x12, 0x00 |
.byte 0x2d, 0x3f, 0x12, 0x00 |
.byte 0x36, 0x3f, 0x12, 0x00 |
.byte 0x3f, 0x3f, 0x12, 0x00 |
.byte 0x00, 0x00, 0x1b, 0x00 |
.byte 0x09, 0x00, 0x1b, 0x00 |
.byte 0x12, 0x00, 0x1b, 0x00 |
.byte 0x1b, 0x00, 0x1b, 0x00 |
.byte 0x24, 0x00, 0x1b, 0x00 |
.byte 0x2d, 0x00, 0x1b, 0x00 |
.byte 0x36, 0x00, 0x1b, 0x00 |
.byte 0x3f, 0x00, 0x1b, 0x00 |
.byte 0x00, 0x15, 0x1b, 0x00 |
.byte 0x09, 0x15, 0x1b, 0x00 |
.byte 0x12, 0x15, 0x1b, 0x00 |
.byte 0x1b, 0x15, 0x1b, 0x00 |
.byte 0x24, 0x15, 0x1b, 0x00 |
.byte 0x2d, 0x15, 0x1b, 0x00 |
.byte 0x36, 0x15, 0x1b, 0x00 |
.byte 0x3f, 0x15, 0x1b, 0x00 |
.byte 0x00, 0x2a, 0x1b, 0x00 |
.byte 0x09, 0x2a, 0x1b, 0x00 |
.byte 0x12, 0x2a, 0x1b, 0x00 |
.byte 0x1b, 0x2a, 0x1b, 0x00 |
.byte 0x24, 0x2a, 0x1b, 0x00 |
.byte 0x2d, 0x2a, 0x1b, 0x00 |
.byte 0x36, 0x2a, 0x1b, 0x00 |
.byte 0x3f, 0x2a, 0x1b, 0x00 |
.byte 0x00, 0x3f, 0x1b, 0x00 |
.byte 0x09, 0x3f, 0x1b, 0x00 |
.byte 0x12, 0x3f, 0x1b, 0x00 |
.byte 0x1b, 0x3f, 0x1b, 0x00 |
.byte 0x24, 0x3f, 0x1b, 0x00 |
.byte 0x2d, 0x3f, 0x1b, 0x00 |
.byte 0x36, 0x3f, 0x1b, 0x00 |
.byte 0x3f, 0x3f, 0x1b, 0x00 |
.byte 0x00, 0x00, 0x24, 0x00 |
.byte 0x09, 0x00, 0x24, 0x00 |
.byte 0x12, 0x00, 0x24, 0x00 |
.byte 0x1b, 0x00, 0x24, 0x00 |
.byte 0x24, 0x00, 0x24, 0x00 |
.byte 0x2d, 0x00, 0x24, 0x00 |
.byte 0x36, 0x00, 0x24, 0x00 |
.byte 0x3f, 0x00, 0x24, 0x00 |
.byte 0x00, 0x15, 0x24, 0x00 |
.byte 0x09, 0x15, 0x24, 0x00 |
.byte 0x12, 0x15, 0x24, 0x00 |
.byte 0x1b, 0x15, 0x24, 0x00 |
.byte 0x24, 0x15, 0x24, 0x00 |
.byte 0x2d, 0x15, 0x24, 0x00 |
.byte 0x36, 0x15, 0x24, 0x00 |
.byte 0x3f, 0x15, 0x24, 0x00 |
.byte 0x00, 0x2a, 0x24, 0x00 |
.byte 0x09, 0x2a, 0x24, 0x00 |
.byte 0x12, 0x2a, 0x24, 0x00 |
.byte 0x1b, 0x2a, 0x24, 0x00 |
.byte 0x24, 0x2a, 0x24, 0x00 |
.byte 0x2d, 0x2a, 0x24, 0x00 |
.byte 0x36, 0x2a, 0x24, 0x00 |
.byte 0x3f, 0x2a, 0x24, 0x00 |
.byte 0x00, 0x3f, 0x24, 0x00 |
.byte 0x09, 0x3f, 0x24, 0x00 |
.byte 0x12, 0x3f, 0x24, 0x00 |
.byte 0x1b, 0x3f, 0x24, 0x00 |
.byte 0x24, 0x3f, 0x24, 0x00 |
.byte 0x2d, 0x3f, 0x24, 0x00 |
.byte 0x36, 0x3f, 0x24, 0x00 |
.byte 0x3f, 0x3f, 0x24, 0x00 |
.byte 0x00, 0x00, 0x2d, 0x00 |
.byte 0x09, 0x00, 0x2d, 0x00 |
.byte 0x12, 0x00, 0x2d, 0x00 |
.byte 0x1b, 0x00, 0x2d, 0x00 |
.byte 0x24, 0x00, 0x2d, 0x00 |
.byte 0x2d, 0x00, 0x2d, 0x00 |
.byte 0x36, 0x00, 0x2d, 0x00 |
.byte 0x3f, 0x00, 0x2d, 0x00 |
.byte 0x00, 0x15, 0x2d, 0x00 |
.byte 0x09, 0x15, 0x2d, 0x00 |
.byte 0x12, 0x15, 0x2d, 0x00 |
.byte 0x1b, 0x15, 0x2d, 0x00 |
.byte 0x24, 0x15, 0x2d, 0x00 |
.byte 0x2d, 0x15, 0x2d, 0x00 |
.byte 0x36, 0x15, 0x2d, 0x00 |
.byte 0x3f, 0x15, 0x2d, 0x00 |
.byte 0x00, 0x2a, 0x2d, 0x00 |
.byte 0x09, 0x2a, 0x2d, 0x00 |
.byte 0x12, 0x2a, 0x2d, 0x00 |
.byte 0x1b, 0x2a, 0x2d, 0x00 |
.byte 0x24, 0x2a, 0x2d, 0x00 |
.byte 0x2d, 0x2a, 0x2d, 0x00 |
.byte 0x36, 0x2a, 0x2d, 0x00 |
.byte 0x3f, 0x2a, 0x2d, 0x00 |
.byte 0x00, 0x3f, 0x2d, 0x00 |
.byte 0x09, 0x3f, 0x2d, 0x00 |
.byte 0x12, 0x3f, 0x2d, 0x00 |
.byte 0x1b, 0x3f, 0x2d, 0x00 |
.byte 0x24, 0x3f, 0x2d, 0x00 |
.byte 0x2d, 0x3f, 0x2d, 0x00 |
.byte 0x36, 0x3f, 0x2d, 0x00 |
.byte 0x3f, 0x3f, 0x2d, 0x00 |
.byte 0x00, 0x00, 0x36, 0x00 |
.byte 0x09, 0x00, 0x36, 0x00 |
.byte 0x12, 0x00, 0x36, 0x00 |
.byte 0x1b, 0x00, 0x36, 0x00 |
.byte 0x24, 0x00, 0x36, 0x00 |
.byte 0x2d, 0x00, 0x36, 0x00 |
.byte 0x36, 0x00, 0x36, 0x00 |
.byte 0x3f, 0x00, 0x36, 0x00 |
.byte 0x00, 0x15, 0x36, 0x00 |
.byte 0x09, 0x15, 0x36, 0x00 |
.byte 0x12, 0x15, 0x36, 0x00 |
.byte 0x1b, 0x15, 0x36, 0x00 |
.byte 0x24, 0x15, 0x36, 0x00 |
.byte 0x2d, 0x15, 0x36, 0x00 |
.byte 0x36, 0x15, 0x36, 0x00 |
.byte 0x3f, 0x15, 0x36, 0x00 |
.byte 0x00, 0x2a, 0x36, 0x00 |
.byte 0x09, 0x2a, 0x36, 0x00 |
.byte 0x12, 0x2a, 0x36, 0x00 |
.byte 0x1b, 0x2a, 0x36, 0x00 |
.byte 0x24, 0x2a, 0x36, 0x00 |
.byte 0x2d, 0x2a, 0x36, 0x00 |
.byte 0x36, 0x2a, 0x36, 0x00 |
.byte 0x3f, 0x2a, 0x36, 0x00 |
.byte 0x00, 0x3f, 0x36, 0x00 |
.byte 0x09, 0x3f, 0x36, 0x00 |
.byte 0x12, 0x3f, 0x36, 0x00 |
.byte 0x1b, 0x3f, 0x36, 0x00 |
.byte 0x24, 0x3f, 0x36, 0x00 |
.byte 0x2d, 0x3f, 0x36, 0x00 |
.byte 0x36, 0x3f, 0x36, 0x00 |
.byte 0x3f, 0x3f, 0x36, 0x00 |
.byte 0x00, 0x00, 0x3f, 0x00 |
.byte 0x09, 0x00, 0x3f, 0x00 |
.byte 0x12, 0x00, 0x3f, 0x00 |
.byte 0x1b, 0x00, 0x3f, 0x00 |
.byte 0x24, 0x00, 0x3f, 0x00 |
.byte 0x2d, 0x00, 0x3f, 0x00 |
.byte 0x36, 0x00, 0x3f, 0x00 |
.byte 0x3f, 0x00, 0x3f, 0x00 |
.byte 0x00, 0x15, 0x3f, 0x00 |
.byte 0x09, 0x15, 0x3f, 0x00 |
.byte 0x12, 0x15, 0x3f, 0x00 |
.byte 0x1b, 0x15, 0x3f, 0x00 |
.byte 0x24, 0x15, 0x3f, 0x00 |
.byte 0x2d, 0x15, 0x3f, 0x00 |
.byte 0x36, 0x15, 0x3f, 0x00 |
.byte 0x3f, 0x15, 0x3f, 0x00 |
.byte 0x00, 0x2a, 0x3f, 0x00 |
.byte 0x09, 0x2a, 0x3f, 0x00 |
.byte 0x12, 0x2a, 0x3f, 0x00 |
.byte 0x1b, 0x2a, 0x3f, 0x00 |
.byte 0x24, 0x2a, 0x3f, 0x00 |
.byte 0x2d, 0x2a, 0x3f, 0x00 |
.byte 0x36, 0x2a, 0x3f, 0x00 |
.byte 0x3f, 0x2a, 0x3f, 0x00 |
.byte 0x00, 0x3f, 0x3f, 0x00 |
.byte 0x09, 0x3f, 0x3f, 0x00 |
.byte 0x12, 0x3f, 0x3f, 0x00 |
.byte 0x1b, 0x3f, 0x3f, 0x00 |
.byte 0x24, 0x3f, 0x3f, 0x00 |
.byte 0x2d, 0x3f, 0x3f, 0x00 |
.byte 0x36, 0x3f, 0x3f, 0x00 |
.byte 0x3f, 0x3f, 0x3f, 0x00 |
/branches/network/kernel/arch/ia32/src/boot/vesa_ret.inc |
---|
0,0 → 1,12 |
.code32 |
vesa_init_protected: |
movw $gdtselector(KDATA_DES), %cx |
movw %cx, %es |
movw %cx, %fs |
movw %cx, %gs |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
movl $START_STACK, %esp # initialize stack pointer |
jmpl $gdtselector(KTEXT_DES), $vesa_meeting_point |
/branches/network/kernel/arch/ia32/src/boot/boot.S |
---|
42,178 → 42,63 |
multiboot_header: |
.long MULTIBOOT_HEADER_MAGIC |
.long MULTIBOOT_HEADER_FLAGS |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum |
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum |
.long multiboot_header |
.long unmapped_ktext_start |
.long 0 |
.long 0 |
.long multiboot_image_start |
multiboot_image_start: |
cld |
movl $START_STACK, %esp # initialize stack pointer |
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register |
movw $selector(KDATA_DES), %cx |
movl $START_STACK, %esp # initialize stack pointer |
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register |
movw $gdtselector(KDATA_DES), %cx |
movw %cx, %es |
movw %cx, %fs |
movw %cx, %gs |
movw %cx, %ds # kernel data + stack |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
jmpl $selector(KTEXT_DES), $multiboot_meeting_point |
jmpl $gdtselector(KTEXT_DES), $multiboot_meeting_point |
multiboot_meeting_point: |
movl %eax, grub_eax # save parameters from GRUB |
movl %eax, grub_eax # save parameters from GRUB |
movl %ebx, grub_ebx |
xorl %eax, %eax |
cpuid |
cmp $0x0, %eax # any function > 0? |
xorl %eax, %eax |
cpuid |
cmp $0x0, %eax # any function > 0? |
jbe pse_unsupported |
movl $0x1, %eax # Basic function code 1 |
movl $0x1, %eax # basic function code 1 |
cpuid |
bt $3, %edx # Test if PSE is supported |
bt $3, %edx # test if PSE is supported |
jc pse_supported |
pse_unsupported: |
movl $pse_msg, %esi |
jmp error_halt |
pse_supported: |
#ifdef CONFIG_FB |
mov $vesa_init, %esi |
mov $VESA_INIT_SEGMENT << 4, %edi |
mov $e_vesa_init - vesa_init, %ecx |
rep movsb |
mov $VESA_INIT_SEGMENT << 4, %edi |
jmpl *%edi |
#include "vesa_prot.inc" |
# map kernel and turn paging on |
call map_kernel |
vesa_meeting_point: |
# call arch_pre_main(grub_eax, grub_ebx) |
pushl grub_ebx |
pushl grub_eax |
call arch_pre_main |
mov %esi, KA2PA(vesa_ph_addr) |
mov %di, KA2PA(vesa_height) |
shr $16, %edi |
mov %di, KA2PA(vesa_width) |
mov %bx, KA2PA(vesa_scanline) |
shr $16, %ebx |
mov %bx, KA2PA(vesa_bpp) |
#endif |
call main_bsp |
call map_kernel # map kernel and turn paging on |
movl grub_eax, %eax |
movl grub_ebx, %ebx |
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature |
je valid_boot |
xorl %ecx, %ecx # no memory map available |
movl %ecx, e820counter |
jmp invalid_boot |
valid_boot: |
movl (%ebx), %eax # ebx = physical address of struct multiboot_info |
bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid) |
jc mods_valid |
xorl %ecx, %ecx |
movl %ecx, init |
jmp mods_end |
mods_valid: |
movl 20(%ebx), %ecx # mbi->mods_count |
movl %ecx, init |
cmpl $0, %ecx |
je mods_end |
movl 24(%ebx), %esi # mbi->mods_addr |
movl $init, %edi |
mods_loop: |
movl 0(%esi), %edx # mods->mod_start |
addl $0x80000000, %edx |
movl %edx, 4(%edi) |
movl 4(%esi), %edx |
subl 0(%esi), %edx # mods->mod_end - mods->mod_start |
movl %edx, 8(%edi) |
addl $16, %esi |
addl $8 , %edi |
loop mods_loop |
mods_end: |
bt $6, %eax # mbi->flags[6] (mmap_length, mmap_addr valid) |
jc mmap_valid |
xorl %edx, %edx |
jmp mmap_invalid |
mmap_valid: |
movl 44(%ebx), %ecx # mbi->mmap_length |
movl 48(%ebx), %esi # mbi->mmap_addr |
movl $e820table, %edi |
xorl %edx, %edx |
mmap_loop: |
cmpl $0, %ecx |
jle mmap_end |
movl 4(%esi), %eax # mmap->base_addr_low |
movl %eax, (%edi) |
movl 8(%esi), %eax # mmap->base_addr_high |
movl %eax, 4(%edi) |
movl 12(%esi), %eax # mmap->length_low |
movl %eax, 8(%edi) |
movl 16(%esi), %eax # mmap->length_high |
movl %eax, 12(%edi) |
movl 20(%esi), %eax # mmap->type |
movl %eax, 16(%edi) |
movl (%esi), %eax # mmap->size |
addl $0x4, %eax |
addl %eax, %esi |
subl %eax, %ecx |
addl $MEMMAP_E820_RECORD_SIZE, %edi |
incl %edx |
jmp mmap_loop |
mmap_end: |
mmap_invalid: |
movl %edx, e820counter |
invalid_boot: |
#ifdef CONFIG_SMP |
# copy AP bootstrap routines below 1 MB |
movl $BOOT_OFFSET, %esi |
movl $AP_BOOT_OFFSET, %edi |
movl $_hardcoded_unmapped_size, %ecx |
rep movsb |
#endif |
call main_bsp # never returns |
# not reached |
cli |
hlt |
hlt0: |
hlt |
jmp hlt0 |
.global map_kernel |
map_kernel: |
222,8 → 107,8 |
# For simplicity, we map the entire 4G space. |
# |
movl %cr4, %ecx |
orl $(1 << 4), %ecx # turn PSE on |
andl $(~(1 << 5)), %ecx # turn PAE off |
orl $(1 << 4), %ecx # turn PSE on |
andl $(~(1 << 5)), %ecx # turn PAE off |
movl %ecx, %cr4 |
movl $(page_directory + 0), %esi |
230,30 → 115,31 |
movl $(page_directory + 2048), %edi |
xorl %ecx, %ecx |
xorl %ebx, %ebx |
0: |
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax |
orl %ebx, %eax |
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
addl $(4 * 1024 * 1024), %ebx |
incl %ecx |
cmpl $512, %ecx |
jl 0b |
floop: |
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax |
orl %ebx, %eax |
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M |
addl $(4 * 1024 * 1024), %ebx |
incl %ecx |
cmpl $512, %ecx |
jl floop |
movl %esi, %cr3 |
movl %cr0, %ebx |
orl $(1 << 31), %ebx # turn paging on |
orl $(1 << 31), %ebx # turn paging on |
movl %ebx, %cr0 |
ret |
# Print string from %esi to EGA display (in red) and halt |
error_halt: |
movl $0xb8000, %edi # base of EGA text mode memory |
movl $0xb8000, %edi # base of EGA text mode memory |
xorl %eax, %eax |
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address |
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address |
movb $0xe, %al |
outb %al, %dx |
261,7 → 147,7 |
inb %dx, %al |
shl $8, %ax |
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address |
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address |
movb $0xf, %al |
outb %al, %dx |
270,7 → 156,9 |
cmp $1920, %ax |
jbe cursor_ok |
movw $1920, %ax # sanity check for the cursor on the last line |
movw $1920, %ax # sanity check for the cursor on the last line |
cursor_ok: |
movw %ax, %bx |
277,7 → 165,7 |
shl $1, %eax |
addl %eax, %edi |
movw $0x0c00, %ax # black background, light red foreground |
movw $0x0c00, %ax # black background, light red foreground |
ploop: |
lodsb |
284,11 → 172,11 |
cmp $0, %al |
je ploop_end |
stosw |
inc %bx |
inc %bx |
jmp ploop |
ploop_end: |
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address |
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address |
movb $0xe, %al |
outb %al, %dx |
296,7 → 184,7 |
movb %bh, %al |
outb %al, %dx |
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address |
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address |
movb $0xf, %al |
outb %al, %dx |
303,240 → 191,14 |
movw $0x3d5, %dx |
movb %bl, %al |
outb %al, %dx |
cli |
hlt |
hlt1: |
hlt |
jmp hlt1 |
#ifdef CONFIG_FB |
vesa_init: |
jmp $selector(VESA_INIT_DES), $vesa_init_real - vesa_init |
.code16 |
vesa_init_real: |
mov %cr0, %eax |
and $~1, %eax |
mov %eax, %cr0 |
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init |
vesa_init_real2: |
mov $VESA_INIT_SEGMENT, %bx |
mov %bx, %es |
mov %bx, %fs |
mov %bx, %gs |
mov %bx, %ds |
mov %bx, %ss |
movl %esp, %eax |
movl $0x0000fffc, %esp |
movl $0x0000fffc, %ebp |
pushl %eax |
#define VESA_INFO_SIZE 1024 |
#include "vesa_real.inc" |
#define VESA_MODE_ATTRIBUTES_OFFSET 0 |
#define VESA_MODE_LIST_PTR_OFFSET 14 |
#define VESA_MODE_SCANLINE_OFFSET 16 |
#define VESA_MODE_WIDTH_OFFSET 18 |
#define VESA_MODE_HEIGHT_OFFSET 20 |
#define VESA_MODE_BPP_OFFSET 25 |
#define VESA_MODE_PHADDR_OFFSET 40 |
#define VESA_END_OF_MODES 0xffff |
#define VESA_OK 0x4f |
#define VESA_GET_INFO 0x4f00 |
#define VESA_GET_MODE_INFO 0x4f01 |
#define VESA_SET_MODE 0x4f02 |
#define VESA_SET_PALETTE 0x4f09 |
#if CONFIG_VESA_BPP == 24 |
#define CONFIG_VESA_BPP_VARIANT 32 |
#endif |
mov $VESA_GET_INFO, %ax |
mov $e_vesa_init - vesa_init, %di |
push %di |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz 0f |
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si |
mov %si, %gs |
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si |
add $VESA_INFO_SIZE, %di |
1:# Try next mode |
mov %gs:(%si), %cx |
cmp $VESA_END_OF_MODES, %cx |
jz 0f |
inc %si |
inc %si |
push %cx |
push %di |
push %si |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %si |
pop %di |
pop %cx |
cmp $VESA_OK, %al |
jnz 0f |
mov $CONFIG_VESA_WIDTH, %ax |
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax |
jnz 1b |
mov $CONFIG_VESA_HEIGHT, %ax |
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax |
jnz 1b |
mov $CONFIG_VESA_BPP, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
#ifdef CONFIG_VESA_BPP_VARIANT |
jz 2f |
mov $CONFIG_VESA_BPP_VARIANT, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
#endif |
jnz 1b |
2: |
mov %cx, %bx |
or $0xc000, %bx |
push %di |
mov $VESA_SET_MODE, %ax |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz 0f |
#if CONFIG_VESA_BPP == 8 |
# Set 3:2:3 VGA palette |
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax |
push %di |
mov $vga323 - vesa_init, %di |
mov $0x100, %ecx |
bt $5, %ax # Test if VGA compatible registers are present |
jnc vga_compat |
# Try VESA routine to set palette |
mov $VESA_SET_PALETTE, %ax |
xor %bl, %bl |
xor %dx, %dx |
int $0x10 |
jmp vga_not_compat |
vga_compat: |
# Try VGA registers to set palette |
movw $0x3c6, %dx # Set palette mask |
movb $0xff, %al |
outb %al, %dx |
movw $0x3c8, %dx # First index to set |
xor %al, %al |
outb %al, %dx |
movw $0x3c9, %dx # Data port |
vga_loop: |
movb %es:2(%di), %al |
outb %al, %dx |
movb %es:1(%di), %al |
outb %al, %dx |
movb %es:(%di), %al |
outb %al, %dx |
addw $4, %di |
loop vga_loop |
vga_not_compat: |
pop %di |
#endif |
mov VESA_MODE_PHADDR_OFFSET(%di), %esi |
mov VESA_MODE_WIDTH_OFFSET(%di), %ax |
shl $16, %eax |
mov VESA_MODE_HEIGHT_OFFSET(%di), %ax |
mov VESA_MODE_BPP_OFFSET(%di), %bl |
xor %bh, %bh |
shl $16, %ebx |
mov VESA_MODE_SCANLINE_OFFSET(%di), %bx |
mov %eax, %edi |
8: |
mov %cr0, %eax |
or $1, %eax |
mov %eax, %cr0 |
jmp 9f |
9: |
ljmpl $selector(KTEXT_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4) |
0:# No prefered mode found |
mov $0x111, %cx |
push %di |
push %cx |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %cx |
pop %di |
cmp $VESA_OK, %al |
jnz 1f |
jz 2b # Force relative jump |
1: |
mov $0x0003, %ax |
int $0x10 |
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA |
xor %ax, %ax |
jz 8b # Force relative jump |
vga323: |
#include "vga323.pal" |
.code32 |
vesa_init_protect: |
movw $selector(KDATA_DES), %cx |
movw %cx, %es |
movw %cx, %fs |
movw %cx, %gs |
movw %cx, %ds # kernel data + stack |
movw %cx, %ss |
movl $START_STACK, %esp # initialize stack pointer |
jmpl $selector(KTEXT_DES), $vesa_meeting_point |
.align 4 |
e_vesa_init: |
#endif |
.section K_DATA_START, "aw", @progbits |
.align 4096 |
/branches/network/kernel/arch/ia32/src/boot/vesa_real.inc |
---|
0,0 → 1,373 |
#ifdef CONFIG_FB |
#include <macros.h> |
#define VESA_INFO_SIZE 1024 |
#define VESA_MODE_ATTRIBUTES_OFFSET 0 |
#define VESA_MODE_LIST_PTR_OFFSET 14 |
#define VESA_MODE_SCANLINE_OFFSET 16 |
#define VESA_MODE_WIDTH_OFFSET 18 |
#define VESA_MODE_HEIGHT_OFFSET 20 |
#define VESA_MODE_BPP_OFFSET 25 |
#define VESA_MODE_RED_MASK_OFFSET 31 |
#define VESA_MODE_RED_POS_OFFSET 32 |
#define VESA_MODE_GREEN_MASK_OFFSET 33 |
#define VESA_MODE_GREEN_POS_OFFSET 34 |
#define VESA_MODE_BLUE_MASK_OFFSET 35 |
#define VESA_MODE_BLUE_POS_OFFSET 36 |
#define VESA_MODE_PHADDR_OFFSET 40 |
#define VESA_END_OF_MODES 0xffff |
#define VESA_OK 0x4f |
#define VESA_GET_INFO 0x4f00 |
#define VESA_GET_MODE_INFO 0x4f01 |
#define VESA_SET_MODE 0x4f02 |
#define VESA_SET_PALETTE 0x4f09 |
.code32 |
vesa_init: |
jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init |
.code16 |
vesa_init_real: |
mov %cr0, %eax |
and $~1, %eax |
mov %eax, %cr0 |
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init |
vesa_init_real2: |
mov $VESA_INIT_SEGMENT, %bx |
mov %bx, %es |
mov %bx, %fs |
mov %bx, %gs |
mov %bx, %ds |
mov %bx, %ss |
movl %esp, %eax |
movl $0x0000fffc, %esp |
movl $0x0000fffc, %ebp |
pushl %eax |
# parse default mode string |
mov $default_mode - vesa_init, %di |
xor %eax, %eax |
xor %ebx, %ebx |
mov $8, %ecx |
parse_width: |
mov (%di), %al |
# check for digit |
cmp $'0', %al |
jb parse_width_done |
cmp $'9', %al |
ja parse_width_done |
sub $'0', %al |
# multiply default_width by 10 and add digit |
mov default_width - vesa_init, %bx |
lea (%ebx, %ebx, 4), %ebx |
shl $1, %ebx |
add %ax, %bx |
mov %bx, default_width - vesa_init |
inc %di |
loop parse_width |
parse_width_done: |
mov (%di), %al |
cmp $0, %al |
jz parse_done |
inc %di |
mov $8, %ecx |
parse_height: |
mov (%di), %al |
# check for digit |
cmp $'0', %al |
jb parse_height_done |
cmp $'9', %al |
ja parse_height_done |
sub $'0', %al |
# multiply default_height by 10 and add digit |
mov default_height - vesa_init, %bx |
lea (%ebx, %ebx, 4), %ebx |
shl $1, %ebx |
add %ax, %bx |
mov %bx, default_height - vesa_init |
inc %di |
loop parse_height |
parse_height_done: |
mov (%di), %al |
cmp $0, %al |
jz parse_done |
inc %di |
mov $4, %ecx |
parse_bpp: |
mov (%di), %al |
# check for digit |
cmp $'0', %al |
jb parse_bpp_done |
cmp $'9', %al |
ja parse_bpp_done |
sub $'0', %al |
# multiply default_bpp by 10 and add digit |
mov default_bpp - vesa_init, %bx |
lea (%ebx, %ebx, 4), %ebx |
shl $1, %ebx |
add %ax, %bx |
mov %bx, default_bpp - vesa_init |
inc %di |
loop parse_bpp |
parse_bpp_done: |
parse_done: |
mov $VESA_GET_INFO, %ax |
mov $e_vesa_init - vesa_init, %di |
push %di |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz no_mode |
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si |
mov %si, %gs |
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si |
add $VESA_INFO_SIZE, %di |
next_mode: |
# try next mode |
mov %gs:(%si), %cx |
cmp $VESA_END_OF_MODES, %cx |
je no_mode |
inc %si |
inc %si |
push %cx |
push %di |
push %si |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %si |
pop %di |
pop %cx |
cmp $VESA_OK, %al |
jne no_mode |
# check for proper attributes (supported, color, graphics, linear framebuffer) |
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax |
and $0x99, %ax |
cmp $0x99, %ax |
jne next_mode |
# check for proper resolution |
mov default_width - vesa_init, %ax |
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax |
jne next_mode |
mov default_height - vesa_init, %ax |
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax |
jne next_mode |
# check for proper bpp |
mov default_bpp - vesa_init, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
je set_mode |
mov $24, %al |
cmp default_bpp - vesa_init, %al |
jne next_mode |
# for 24 bpp modes accept also 32 bit bpp |
mov $32, %al |
cmp VESA_MODE_BPP_OFFSET(%di), %al |
jne next_mode |
set_mode: |
mov %cx, %bx |
or $0xc000, %bx |
push %di |
mov $VESA_SET_MODE, %ax |
int $0x10 |
pop %di |
cmp $VESA_OK, %al |
jnz no_mode |
# set 3:2:3 VGA palette |
mov VESA_MODE_BPP_OFFSET(%di), %al |
cmp $8, %al |
jnz vga_not_set |
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax |
push %di |
mov $vga323 - vesa_init, %di |
mov $0x100, %ecx |
bt $5, %ax # test if VGA compatible registers are present |
jnc vga_compat |
# try VESA routine to set palette |
mov $VESA_SET_PALETTE, %ax |
xor %bl, %bl |
xor %dx, %dx |
int $0x10 |
cmp $0x00, %ah |
je vga_not_compat |
vga_compat: |
# try VGA registers to set palette |
movw $0x3c6, %dx # set palette mask |
movb $0xff, %al |
outb %al, %dx |
movw $0x3c8, %dx # first index to set |
xor %al, %al |
outb %al, %dx |
movw $0x3c9, %dx # data port |
vga_loop: |
movb %es:2(%di), %al |
outb %al, %dx |
movb %es:1(%di), %al |
outb %al, %dx |
movb %es:(%di), %al |
outb %al, %dx |
addw $4, %di |
loop vga_loop |
vga_not_compat: |
pop %di |
vga_not_set: |
# store mode parameters |
# eax = bpp[8] scanline[16] |
# ebx = width[16] height[16] |
# edx = red_mask[8] red_pos[8] green_mask[8] green_pos[8] |
# esi = blue_mask[8] blue_pos[8] |
# edi = linear frame buffer |
mov VESA_MODE_BPP_OFFSET(%di), %al |
xor %ah, %ah |
shl $16, %eax |
mov VESA_MODE_SCANLINE_OFFSET(%di), %ax |
mov VESA_MODE_WIDTH_OFFSET(%di), %bx |
shl $16, %ebx |
mov VESA_MODE_HEIGHT_OFFSET(%di), %bx |
mov VESA_MODE_BLUE_MASK_OFFSET(%di), %dl |
shl $8, %edx |
mov VESA_MODE_BLUE_POS_OFFSET(%di), %dl |
mov %edx, %esi |
mov VESA_MODE_RED_MASK_OFFSET(%di), %dl |
shl $8, %edx |
mov VESA_MODE_RED_POS_OFFSET(%di), %dl |
shl $8, %edx |
mov VESA_MODE_GREEN_MASK_OFFSET(%di), %dl |
shl $8, %edx |
mov VESA_MODE_GREEN_POS_OFFSET(%di), %dl |
mov VESA_MODE_PHADDR_OFFSET(%di), %edi |
vesa_leave_real: |
mov %cr0, %ecx |
or $1, %ecx |
mov %ecx, %cr0 |
jmp vesa_leave_real2 |
vesa_leave_real2: |
ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4) |
no_mode: |
# no prefered mode found |
mov $0x111, %cx |
push %di |
push %cx |
mov $VESA_GET_MODE_INFO, %ax |
int $0x10 |
pop %cx |
pop %di |
cmp $VESA_OK, %al |
jnz text_mode |
jz set_mode # force relative jump |
text_mode: |
# reset to EGA text mode (because of problems with VESA) |
mov $0x0003, %ax |
int $0x10 |
mov $0xffffffff, %edi |
xor %ax, %ax |
jz vesa_leave_real # force relative jump |
vga323: |
#include "vga323.pal" |
default_width: |
.word 0 |
default_height: |
.word 0 |
default_bpp: |
.byte 0 |
default_mode: |
.ascii STRING(CONFIG_VESA_MODE) |
.ascii "-" |
.asciz STRING(CONFIG_VESA_BPP) |
.fill 24 |
#include "vesa_ret.inc" |
.align 4 |
e_vesa_init: |
#endif |
/branches/network/kernel/arch/ia32/src/boot/vesa_prot.inc |
---|
0,0 → 1,107 |
#ifdef CONFIG_FB |
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002 |
#define MBINFO_BIT_CMDLINE 2 |
#define MBINFO_OFFSET_CMDLINE 16 |
# copy real mode VESA initialization code |
mov $vesa_init, %esi |
mov $VESA_INIT_SEGMENT << 4, %edi |
mov $e_vesa_init - vesa_init, %ecx |
rep movsb |
# check for GRUB command line |
mov grub_eax, %eax |
cmp $MULTIBOOT_LOADER_MAGIC, %eax |
jne no_cmdline |
mov grub_ebx, %ebx |
mov (%ebx), %eax |
bt $MBINFO_BIT_CMDLINE, %eax |
jnc no_cmdline |
# skip the kernel path in command line |
mov MBINFO_OFFSET_CMDLINE(%ebx), %esi |
skip_loop: |
lodsb |
cmp $0, %al |
je no_cmdline |
cmp $' ', %al |
je skip_loop_done |
jmp skip_loop |
skip_loop_done: |
space_loop: |
mov (%esi), %al |
cmp $0, %al |
je no_cmdline |
cmp $' ', %al |
jne space_loop_done |
inc %esi |
jmp space_loop |
space_loop_done: |
# copy at most 23 characters from command line |
mov $VESA_INIT_SEGMENT << 4, %edi |
add $default_mode - vesa_init, %edi |
mov $23, %ecx |
cmd_loop: |
lodsb |
stosb |
cmp $0, %al |
je cmd_loop_done |
loop cmd_loop |
cmd_loop_done: |
# zero termination |
xor %eax, %eax |
stosb |
no_cmdline: |
# jump to the real mode |
mov $VESA_INIT_SEGMENT << 4, %edi |
jmpl *%edi |
vesa_meeting_point: |
# returned back to protected mode |
mov %ax, KA2PA(vesa_scanline) |
shr $16, %eax |
mov %ax, KA2PA(vesa_bpp) |
mov %bx, KA2PA(vesa_height) |
shr $16, %ebx |
mov %bx, KA2PA(vesa_width) |
mov %dl, KA2PA(vesa_green_pos) |
shr $8, %edx |
mov %dl, KA2PA(vesa_green_mask) |
shr $8, %edx |
mov %dl, KA2PA(vesa_red_pos) |
shr $8, %edx |
mov %dl, KA2PA(vesa_red_mask) |
mov %esi, %edx |
mov %dl, KA2PA(vesa_blue_pos) |
shr $8, %edx |
mov %dl, KA2PA(vesa_blue_mask) |
mov %edi, KA2PA(vesa_ph_addr) |
#endif |
/branches/network/kernel/arch/ia32/src/proc/scheduler.c |
---|
38,7 → 38,6 |
#include <proc/thread.h> |
#include <arch.h> |
#include <arch/context.h> /* SP_DELTA */ |
#include <arch/debugger.h> |
#include <arch/pm.h> |
#include <arch/asm.h> |
#include <arch/ddi/ddi.h> |
58,21 → 57,18 |
*/ |
void before_thread_runs_arch(void) |
{ |
CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
SP_DELTA]; |
CPU->arch.tss->ss0 = selector(KDATA_DES); |
/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */ |
write_msr(IA32_MSR_SYSENTER_ESP, kstk); |
/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */ |
CPU->arch.tss->esp0 = kstk; |
CPU->arch.tss->ss0 = gdtselector(KDATA_DES); |
/* Set up TLS in GS register */ |
set_tls_desc(THREAD->arch.tls); |
#ifdef CONFIG_DEBUG_AS_WATCHPOINT |
/* Set watchpoint on AS to ensure that nobody sets it to zero */ |
if (CPU->id < BKPOINTS_MAX) { |
the_t *the = THE; |
breakpoint_add(&((the_t *) the->thread->kstack)->as, |
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, the->cpu->id); |
} |
#endif |
} |
void after_thread_ran_arch(void) |
/branches/network/kernel/arch/ia32/src/mm/tlb.c |
---|
67,5 → 67,13 |
invlpg(page + i * PAGE_SIZE); |
} |
void tlb_arch_init(void) |
{ |
} |
void tlb_print(void) |
{ |
} |
/** @} |
*/ |
/branches/network/kernel/arch/ia32/src/mm/frame.c |
---|
54,26 → 54,57 |
static void init_e820_memory(pfn_t minconf) |
{ |
unsigned int i; |
pfn_t start, conf; |
size_t size; |
for (i = 0; i < e820counter; i++) { |
uint64_t base = e820table[i].base_address; |
uint64_t size = e820table[i].size; |
#ifdef __32_BITS__ |
/* Ignore physical memory above 4 GB */ |
if ((base >> 32) != 0) |
continue; |
/* Clip regions above 4 GB */ |
if (((base + size) >> 32) != 0) |
size = 0xffffffff - base; |
#endif |
pfn_t pfn; |
count_t count; |
if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { |
start = ADDR2PFN(ALIGN_UP(e820table[i].base_address, FRAME_SIZE)); |
size = SIZE2FRAMES(ALIGN_DOWN(e820table[i].size, FRAME_SIZE)); |
/* To be safe, make available zone possibly smaller */ |
pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)); |
if ((minconf < start) || (minconf >= start + size)) |
conf = start; |
pfn_t conf; |
if ((minconf < pfn) || (minconf >= pfn + count)) |
conf = pfn; |
else |
conf = minconf; |
zone_create(start, size, conf, 0); |
zone_create(pfn, count, conf, ZONE_AVAILABLE); |
if (last_frame < ALIGN_UP(e820table[i].base_address + |
e820table[i].size, FRAME_SIZE)) |
last_frame = |
ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE); |
} |
// XXX this has to be removed |
if (last_frame < ALIGN_UP(base + size, FRAME_SIZE)) |
last_frame = ALIGN_UP(base + size, FRAME_SIZE); |
} |
if (e820table[i].type == MEMMAP_MEMORY_RESERVED) { |
/* To be safe, make reserved zone possibly larger */ |
pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE)); |
zone_create(pfn, count, 0, ZONE_RESERVED); |
} |
if (e820table[i].type == MEMMAP_MEMORY_ACPI) { |
/* To be safe, make firmware zone possibly larger */ |
pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE)); |
zone_create(pfn, count, 0, ZONE_FIRMWARE); |
} |
} |
} |
113,16 → 144,14 |
if (config.cpu_active == 1) { |
minconf = 1; |
#ifdef CONFIG_SMP |
minconf = max(minconf, |
ADDR2PFN(AP_BOOT_OFFSET + hardcoded_unmapped_ktext_size + |
hardcoded_unmapped_kdata_size)); |
#endif |
#ifdef CONFIG_SIMICS_FIX |
minconf = max(minconf, ADDR2PFN(0x10000)); |
#endif |
init_e820_memory(minconf); |
/* Reserve frame 0 (BIOS data) */ |
frame_mark_unavailable(0, 1); |
131,12 → 160,7 |
frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH, |
(hardcoded_unmapped_ktext_size + |
hardcoded_unmapped_kdata_size) >> FRAME_WIDTH); |
#ifdef CONFIG_SIMICS_FIX |
/* Don't know why, but these addresses help */ |
frame_mark_unavailable(0xd000 >> FRAME_WIDTH, 3); |
#endif |
#endif |
} |
} |
/branches/network/kernel/arch/ia32/src/mm/page.c |
---|
53,7 → 53,7 |
{ |
uintptr_t cur; |
int flags; |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
66,12 → 66,12 |
flags |= PAGE_GLOBAL; |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
exc_register(14, "page_fault", (iroutine) page_fault); |
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); |
} else |
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); |
paging_on(); |
} |
79,7 → 79,7 |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%d bytes)", physaddr, size) |
panic("Unable to map physical memory %p (%d bytes).", physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
101,8 → 101,8 |
page = read_cr2(); |
if (istate->error_word & PFERR_CODE_RSVD) |
panic("Reserved bit set in page directory.\n"); |
panic("Reserved bit set in page directory."); |
if (istate->error_word & PFERR_CODE_RW) |
access = PF_ACCESS_WRITE; |
else |
109,11 → 109,11 |
access = PF_ACCESS_READ; |
if (as_page_fault(page, access, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault: %#x", page); |
fault_if_from_uspace(istate, "Page fault: %#x.", page); |
decode_istate(istate); |
printf("page fault address: %#lx\n", page); |
panic("page fault\n"); |
panic("Page fault."); |
} |
} |
/branches/network/kernel/arch/ia32/src/userspace.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
47,10 → 47,8 |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
ipl_t ipl = interrupts_disable(); |
asm volatile ( |
/* |
* Clear nested task flag. |
60,35 → 58,33 |
"and $0xffffbfff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
/* Set up GS register (TLS) */ |
"movl %6, %%gs\n" |
"pushl %0\n" |
"pushl %1\n" |
"pushl %2\n" |
"pushl %3\n" |
"pushl %4\n" |
"movl %5, %%eax\n" |
"movl %[tls_des], %%gs\n" |
"pushl %[udata_des]\n" |
"pushl %[stack_size]\n" |
"pushl %[ipl]\n" |
"pushl %[utext_des]\n" |
"pushl %[entry]\n" |
"movl %[uarg], %%eax\n" |
/* %ebx is defined to hold pcb_ptr - set it to 0 */ |
"xorl %%ebx, %%ebx\n" |
"xorl %%ebx, %%ebx\n" |
"iret\n" |
: |
: "i" (selector(UDATA_DES) | PL_USER), |
"r" ((uint8_t *) kernel_uarg->uspace_stack + |
THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (selector(UTEXT_DES) | PL_USER), |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg), |
"r" (selector(TLS_DES)) |
: |
: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER), |
[stack_size] "r" ((uint8_t *) kernel_uarg->uspace_stack + THREAD_STACK_SIZE), |
[ipl] "r" (ipl), |
[utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER), |
[entry] "r" (kernel_uarg->uspace_entry), |
[uarg] "r" (kernel_uarg->uspace_uarg), |
[tls_des] "r" (gdtselector(TLS_DES)) |
: "eax"); |
/* Unreachable */ |
for(;;) |
; |
while (1); |
} |
/** @} |
/branches/network/kernel/arch/ia32/src/interrupt.c |
---|
44,7 → 44,6 |
#include <mm/tlb.h> |
#include <mm/as.h> |
#include <arch.h> |
#include <symtab.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <synch/spinlock.h> |
52,6 → 51,7 |
#include <ipc/sysipc.h> |
#include <interrupt.h> |
#include <ddi/irq.h> |
#include <symtab.h> |
/* |
* Interrupt and exception dispatching. |
63,10 → 63,9 |
void decode_istate(istate_t *istate) |
{ |
char *symbol = get_symtab_entry(istate->eip); |
char *symbol; |
if (!symbol) |
symbol = ""; |
symbol = symtab_fmt_name_lookup(istate->eip); |
if (CPU) |
printf("----------------EXCEPTION OCCURED (cpu%u)----------------\n", CPU->id); |
77,9 → 76,6 |
printf("ERROR_WORD=%#lx\n", istate->error_word); |
printf("%%cs=%#lx,flags=%#lx\n", istate->cs, istate->eflags); |
printf("%%eax=%#lx, %%ecx=%#lx, %%edx=%#lx, %%esp=%p\n", istate->eax, istate->ecx, istate->edx, &istate->stack[0]); |
#ifdef CONFIG_DEBUG_ALLREGS |
printf("%%esi=%#lx, %%edi=%#lx, %%ebp=%#lx, %%ebx=%#lx\n", istate->esi, istate->edi, istate->ebp, istate->ebx); |
#endif |
printf("stack: %#lx, %#lx, %#lx, %#lx\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]); |
printf(" %#lx, %#lx, %#lx, %#lx\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]); |
} |
89,16 → 85,16 |
if (eoi_function) |
eoi_function(); |
else |
panic("no eoi_function\n"); |
panic("No eoi_function."); |
} |
static void null_interrupt(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "unserviced interrupt: %d", n); |
fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n); |
decode_istate(istate); |
panic("unserviced interrupt: %d\n", n); |
panic("Unserviced interrupt: %d.", n); |
} |
/** General Protection Fault. */ |
122,19 → 118,19 |
io_perm_bitmap_install(); |
return; |
} |
fault_if_from_uspace(istate, "general protection fault"); |
fault_if_from_uspace(istate, "General protection fault."); |
} |
decode_istate(istate); |
panic("general protection fault\n"); |
panic("General protection fault."); |
} |
static void ss_fault(int n __attribute__((unused)), istate_t *istate) |
{ |
fault_if_from_uspace(istate, "stack fault"); |
fault_if_from_uspace(istate, "Stack fault."); |
decode_istate(istate); |
panic("stack fault\n"); |
panic("Stack fault."); |
} |
static void simd_fp_exception(int n __attribute__((unused)), istate_t *istate) |
141,15 → 137,15 |
{ |
uint32_t mxcsr; |
asm ( |
"stmxcsr %0;\n" |
: "=m" (mxcsr) |
"stmxcsr %[mxcsr]\n" |
: [mxcsr] "=m" (mxcsr) |
); |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx", |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx.", |
(unative_t) mxcsr); |
decode_istate(istate); |
printf("MXCSR: %#lx\n", mxcsr); |
panic("SIMD FP exception(19)\n"); |
panic("SIMD FP exception(19)."); |
} |
static void nm_fault(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) |
157,8 → 153,8 |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "fpu fault"); |
panic("fpu fault"); |
fault_if_from_uspace(istate, "FPU fault."); |
panic("FPU fault."); |
#endif |
} |
191,7 → 187,7 |
trap_virtual_eoi(); |
ack = true; |
} |
irq->handler(irq, irq->arg); |
irq->handler(irq); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
233,7 → 229,7 |
if (enable_irqs_function) |
enable_irqs_function(irqmask); |
else |
panic("no enable_irqs_function\n"); |
panic("No enable_irqs_function."); |
} |
void trap_virtual_disable_irqs(uint16_t irqmask) |
241,7 → 237,7 |
if (disable_irqs_function) |
disable_irqs_function(irqmask); |
else |
panic("no disable_irqs_function\n"); |
panic("No disable_irqs_function."); |
} |
/** @} |
/branches/network/kernel/arch/ia32/src/drivers/ega.c |
---|
File deleted |
/branches/network/kernel/arch/ia32/src/drivers/vesa.c |
---|
56,12 → 56,20 |
uint16_t vesa_bpp; |
uint16_t vesa_scanline; |
uint8_t vesa_red_mask; |
uint8_t vesa_red_pos; |
uint8_t vesa_green_mask; |
uint8_t vesa_green_pos; |
uint8_t vesa_blue_mask; |
uint8_t vesa_blue_pos; |
int vesa_present(void) |
{ |
if (vesa_width != 0xffff) |
if ((vesa_width != 0xffff) && (vesa_height != 0xffff)) |
return true; |
if (vesa_height != 0xffff) |
return true; |
return false; |
} |
74,7 → 82,12 |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
visual = VISUAL_RGB_5_6_5; |
if ((vesa_red_mask == 5) && (vesa_red_pos == 10) |
&& (vesa_green_mask == 5) && (vesa_green_pos == 5) |
&& (vesa_blue_mask == 5) && (vesa_blue_pos == 0)) |
visual = VISUAL_RGB_5_5_5; |
else |
visual = VISUAL_RGB_5_6_5; |
break; |
case 24: |
visual = VISUAL_RGB_8_8_8; |
83,12 → 96,25 |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
panic("Unsupported bits per pixel"); |
panic("Unsupported bits per pixel."); |
} |
fb_init(vesa_ph_addr, vesa_width, vesa_height, vesa_scanline, visual); |
fb_properties_t vesa_props = { |
.addr = vesa_ph_addr, |
.offset = 0, |
.x = vesa_width, |
.y = vesa_height, |
.scan = vesa_scanline, |
.visual = visual, |
}; |
fb_init(&vesa_props); |
} |
void vesa_redraw(void) |
{ |
fb_redraw(); |
} |
#endif |
/** @} |
/branches/network/kernel/arch/ia32/src/drivers/i8259.c |
---|
49,28 → 49,28 |
void i8259_init(void) |
{ |
/* ICW1: this is ICW1, ICW4 to follow */ |
outb(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4); |
pio_write_8(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4); |
/* ICW2: IRQ 0 maps to INT IRQBASE */ |
outb(PIC_PIC0PORT2, IVT_IRQBASE); |
pio_write_8(PIC_PIC0PORT2, IVT_IRQBASE); |
/* ICW3: pic1 using IRQ IRQ_PIC1 */ |
outb(PIC_PIC0PORT2, 1 << IRQ_PIC1); |
pio_write_8(PIC_PIC0PORT2, 1 << IRQ_PIC1); |
/* ICW4: i8086 mode */ |
outb(PIC_PIC0PORT2, 1); |
pio_write_8(PIC_PIC0PORT2, 1); |
/* ICW1: ICW1, ICW4 to follow */ |
outb(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4); |
pio_write_8(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4); |
/* ICW2: IRQ 8 maps to INT (IVT_IRQBASE + 8) */ |
outb(PIC_PIC1PORT2, IVT_IRQBASE + 8); |
pio_write_8(PIC_PIC1PORT2, IVT_IRQBASE + 8); |
/* ICW3: pic1 is known as IRQ_PIC1 */ |
outb(PIC_PIC1PORT2, IRQ_PIC1); |
pio_write_8(PIC_PIC1PORT2, IRQ_PIC1); |
/* ICW4: i8086 mode */ |
outb(PIC_PIC1PORT2, 1); |
pio_write_8(PIC_PIC1PORT2, 1); |
/* |
* Register interrupt handler for the PIC spurious interrupt. |
94,12 → 94,12 |
uint8_t x; |
if (irqmask & 0xff) { |
x = inb(PIC_PIC0PORT2); |
outb(PIC_PIC0PORT2, (uint8_t) (x & (~(irqmask & 0xff)))); |
x = pio_read_8(PIC_PIC0PORT2); |
pio_write_8(PIC_PIC0PORT2, (uint8_t) (x & (~(irqmask & 0xff)))); |
} |
if (irqmask >> 8) { |
x = inb(PIC_PIC1PORT2); |
outb(PIC_PIC1PORT2, (uint8_t) (x & (~(irqmask >> 8)))); |
x = pio_read_8(PIC_PIC1PORT2); |
pio_write_8(PIC_PIC1PORT2, (uint8_t) (x & (~(irqmask >> 8)))); |
} |
} |
108,19 → 108,19 |
uint8_t x; |
if (irqmask & 0xff) { |
x = inb(PIC_PIC0PORT2); |
outb(PIC_PIC0PORT2, (uint8_t) (x | (irqmask & 0xff))); |
x = pio_read_8(PIC_PIC0PORT2); |
pio_write_8(PIC_PIC0PORT2, (uint8_t) (x | (irqmask & 0xff))); |
} |
if (irqmask >> 8) { |
x = inb(PIC_PIC1PORT2); |
outb(PIC_PIC1PORT2, (uint8_t) (x | (irqmask >> 8))); |
x = pio_read_8(PIC_PIC1PORT2); |
pio_write_8(PIC_PIC1PORT2, (uint8_t) (x | (irqmask >> 8))); |
} |
} |
void pic_eoi(void) |
{ |
outb(0x20, 0x20); |
outb(0xa0, 0x20); |
pio_write_8((ioport8_t *)0x20, 0x20); |
pio_write_8((ioport8_t *)0xa0, 0x20); |
} |
void pic_spurious(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) |
/branches/network/kernel/arch/ia32/src/drivers/i8254.c |
---|
26,12 → 26,12 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** |
* @file |
* @brief i8254 chip driver. |
* @brief i8254 chip driver. |
* |
* Low level time functions. |
*/ |
53,8 → 53,8 |
#include <ddi/irq.h> |
#include <ddi/device.h> |
#define CLK_PORT1 0x40 |
#define CLK_PORT4 0x43 |
#define CLK_PORT1 ((ioport8_t *)0x40) |
#define CLK_PORT4 ((ioport8_t *)0x43) |
#define CLK_CONST 1193180 |
#define MAGIC_NUMBER 1194 |
61,12 → 61,12 |
static irq_t i8254_irq; |
static irq_ownership_t i8254_claim(void) |
static irq_ownership_t i8254_claim(irq_t *irq) |
{ |
return IRQ_ACCEPT; |
} |
static void i8254_irq_handler(irq_t *irq, void *arg __attribute__((unused)), ...) |
static void i8254_irq_handler(irq_t *irq) |
{ |
/* |
* This IRQ is responsible for kernel preemption. |
94,10 → 94,10 |
void i8254_normal_operation(void) |
{ |
outb(CLK_PORT4, 0x36); |
pio_write_8(CLK_PORT4, 0x36); |
pic_disable_irqs(1 << IRQ_CLK); |
outb(CLK_PORT1, (CLK_CONST / HZ) & 0xf); |
outb(CLK_PORT1, (CLK_CONST / HZ) >> 8); |
pio_write_8(CLK_PORT1, (CLK_CONST / HZ) & 0xf); |
pio_write_8(CLK_PORT1, (CLK_CONST / HZ) >> 8); |
pic_enable_irqs(1 << IRQ_CLK); |
} |
114,36 → 114,36 |
* One-shot timer. Count-down from 0xffff at 1193180Hz |
* MAGIC_NUMBER is the magic value for 1ms. |
*/ |
outb(CLK_PORT4, 0x30); |
outb(CLK_PORT1, 0xff); |
outb(CLK_PORT1, 0xff); |
pio_write_8(CLK_PORT4, 0x30); |
pio_write_8(CLK_PORT1, 0xff); |
pio_write_8(CLK_PORT1, 0xff); |
do { |
/* will read both status and count */ |
outb(CLK_PORT4, 0xc2); |
not_ok = (uint8_t) ((inb(CLK_PORT1) >> 6) & 1); |
t1 = inb(CLK_PORT1); |
t1 |= inb(CLK_PORT1) << 8; |
pio_write_8(CLK_PORT4, 0xc2); |
not_ok = (uint8_t) ((pio_read_8(CLK_PORT1) >> 6) & 1); |
t1 = pio_read_8(CLK_PORT1); |
t1 |= pio_read_8(CLK_PORT1) << 8; |
} while (not_ok); |
asm_delay_loop(LOOPS); |
outb(CLK_PORT4, 0xd2); |
t2 = inb(CLK_PORT1); |
t2 |= inb(CLK_PORT1) << 8; |
pio_write_8(CLK_PORT4, 0xd2); |
t2 = pio_read_8(CLK_PORT1); |
t2 |= pio_read_8(CLK_PORT1) << 8; |
/* |
* We want to determine the overhead of the calibrating mechanism. |
*/ |
outb(CLK_PORT4, 0xd2); |
o1 = inb(CLK_PORT1); |
o1 |= inb(CLK_PORT1) << 8; |
pio_write_8(CLK_PORT4, 0xd2); |
o1 = pio_read_8(CLK_PORT1); |
o1 |= pio_read_8(CLK_PORT1) << 8; |
asm_fake_loop(LOOPS); |
outb(CLK_PORT4, 0xd2); |
o2 = inb(CLK_PORT1); |
o2 |= inb(CLK_PORT1) << 8; |
pio_write_8(CLK_PORT4, 0xd2); |
o2 = pio_read_8(CLK_PORT1); |
o2 |= pio_read_8(CLK_PORT1) << 8; |
CPU->delay_loop_const = |
((MAGIC_NUMBER * LOOPS) / 1000) / ((t1 - t2) - (o1 - o2)) + |