Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4342 → Rev 4343

/branches/dynload/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/dynload/kernel/test/debug/mips1.def
1,4 → 1,3
#ifdef mips32
{
"mips1",
"MIPS debug test",
5,4 → 4,3
&test_mips1,
false
},
#endif
/branches/dynload/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>
49,5 → 47,3
return "Back from debug mode";
}
 
#endif
/branches/dynload/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/dynload/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/dynload/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/dynload/kernel/test/fpu/fpu1.c
File deleted
/branches/dynload/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/dynload/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/dynload/kernel/genarch/include/kbd/z8530.h
49,8 → 49,8
extern void z8530_release(void);
extern void z8530_interrupt(void);
extern char z8530_key_read(chardev_t *);
extern irq_ownership_t z8530_claim(void);
extern void z8530_irq_handler(irq_t *, void *, ...);
extern irq_ownership_t z8530_claim(void *);
extern void z8530_irq_handler(irq_t *);
 
#endif
 
/branches/dynload/kernel/genarch/include/kbd/ns16550.h
37,7 → 37,7
#ifndef KERN_NS16550_H_
#define KERN_NS16550_H_
 
#include <console/chardev.h>
#include <console/chardev.h>
#include <ddi/irq.h>
#include <ipc/irq.h>
 
46,13 → 46,12
extern void ns16550_grab(void);
extern void ns16550_release(void);
extern char ns16550_key_read(chardev_t *);
extern irq_ownership_t ns16550_claim(void);
extern void ns16550_irq_handler(irq_t *, void *, ...);
extern irq_ownership_t ns16550_claim(void *);
extern void ns16550_irq_handler(irq_t *);
 
#include <arch/types.h>
#ifndef ia64
#include <arch/drivers/kbd.h>
#endif
 
/* NS16550 registers */
#define RBR_REG 0 /** Receiver Buffer Register. */
#define IER_REG 1 /** Interrupt Enable Register. */
77,56 → 76,56
 
static inline uint8_t ns16550_rbr_read(ns16550_t *dev)
{
return inb(dev->io_port + RBR_REG);
return pio_read_8(dev->io_port + RBR_REG);
}
static inline void ns16550_rbr_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port + RBR_REG, v);
pio_write_8(dev->io_port + RBR_REG, v);
}
 
static inline uint8_t ns16550_ier_read(ns16550_t *dev)
{
return inb(dev->io_port + IER_REG);
return pio_read_8(dev->io_port + IER_REG);
}
 
static inline void ns16550_ier_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port + IER_REG, v);
pio_write_8(dev->io_port + IER_REG, v);
}
 
static inline uint8_t ns16550_iir_read(ns16550_t *dev)
{
return inb(dev->io_port + IIR_REG);
return pio_read_8(dev->io_port + IIR_REG);
}
 
static inline void ns16550_fcr_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port + FCR_REG, v);
pio_write_8(dev->io_port + FCR_REG, v);
}
 
static inline uint8_t ns16550_lcr_read(ns16550_t *dev)
{
return inb(dev->io_port + LCR_REG);
return pio_read_8(dev->io_port + LCR_REG);
}
 
static inline void ns16550_lcr_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port + LCR_REG, v);
pio_write_8(dev->io_port + LCR_REG, v);
}
 
static inline uint8_t ns16550_lsr_read(ns16550_t *dev)
{
return inb(dev->io_port + LSR_REG);
return pio_read_8(dev->io_port + LSR_REG);
}
 
static inline uint8_t ns16550_mcr_read(ns16550_t *dev)
{
return inb(dev->io_port + MCR_REG);
return pio_read_8(dev->io_port + MCR_REG);
}
 
static inline void ns16550_mcr_write(ns16550_t *dev, uint8_t v)
{
outb(dev->io_port + MCR_REG, v);
pio_write_8(dev->io_port + MCR_REG, v);
}
 
#endif
/branches/dynload/kernel/genarch/src/kbd/ns16550.c
138,11 → 138,9
sysinfo_set_item_val("kbd.address.virtual", NULL, port);
sysinfo_set_item_val("kbd.port", NULL, port);
#ifdef CONFIG_NS16550_INTERRUPT_DRIVEN
/* Enable interrupts */
ns16550_ier_write(&ns16550, IER_ERBFI);
ns16550_mcr_write(&ns16550, MCR_OUT2);
#endif
uint8_t c;
// This switches rbr & ier to mode when accept baudrate constant
198,28 → 196,6
*/
void ns16550_poll(void)
{
#ifndef CONFIG_NS16550_INTERRUPT_DRIVEN
ipl_t ipl;
 
ipl = interrupts_disable();
spinlock_lock(&ns16550_irq.lock);
 
if (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) {
if (ns16550_irq.notif_cfg.notify && ns16550_irq.notif_cfg.answerbox) {
/*
* Send IPC notification.
*/
ipc_irq_send_notif(&ns16550_irq);
spinlock_unlock(&ns16550_irq.lock);
interrupts_restore(ipl);
return;
}
}
 
spinlock_unlock(&ns16550_irq.lock);
interrupts_restore(ipl);
#endif
 
while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) {
uint8_t x;
234,12 → 210,12
}
}
 
irq_ownership_t ns16550_claim(void)
irq_ownership_t ns16550_claim(void *instance)
{
return (ns16550_lsr_read(&ns16550) & LSR_DATA_READY);
}
 
void ns16550_irq_handler(irq_t *irq, void *arg, ...)
void ns16550_irq_handler(irq_t *irq)
{
if (irq->notif_cfg.notify && irq->notif_cfg.answerbox)
ipc_irq_send_notif(irq);
/branches/dynload/kernel/genarch/src/kbd/i8042.c
123,12 → 123,12
interrupts_restore(ipl);
}
 
static irq_ownership_t i8042_claim(void)
static irq_ownership_t i8042_claim(void *instance)
{
return IRQ_ACCEPT;
}
 
static void i8042_irq_handler(irq_t *irq, void *arg, ...)
static void i8042_irq_handler(irq_t *irq)
{
if (irq->notif_cfg.notify && irq->notif_cfg.answerbox)
ipc_irq_send_notif(irq);
/branches/dynload/kernel/genarch/src/kbd/z8530.c
194,12 → 194,12
}
}
 
irq_ownership_t z8530_claim(void)
irq_ownership_t z8530_claim(void *instance)
{
return (z8530_read_a(&z8530, RR0) & RR0_RCA);
}
 
void z8530_irq_handler(irq_t *irq, void *arg, ...)
void z8530_irq_handler(irq_t *irq)
{
if (irq->notif_cfg.notify && irq->notif_cfg.answerbox)
ipc_irq_send_notif(irq);
/branches/dynload/kernel/genarch/src/fb/fb.c
52,9 → 52,6
 
SPINLOCK_INITIALIZE(fb_lock);
 
/**< Physical memory area for fb. */
static parea_t fb_parea;
 
static uint8_t *fb_addr;
static uint8_t *backbuf;
static uint8_t *glyphs;
519,12 → 516,6
fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize);
fb_parea.pbase = (uintptr_t) props->addr + props->offset;
fb_parea.vbase = (uintptr_t) fb_addr;
fb_parea.frames = SIZE2FRAMES(fbsize);
fb_parea.cacheable = false;
ddi_parea_register(&fb_parea);
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 1);
sysinfo_set_item_val("fb.width", NULL, xres);
/branches/dynload/kernel/genarch/src/drivers/ega/ega.c
54,8 → 54,6
* Simple and short. Function for displaying characters and "scrolling".
*/
 
static parea_t ega_parea; /**< Physical memory area for EGA video RAM. */
 
SPINLOCK_INITIALIZE(egalock);
static uint32_t ega_cursor;
static uint8_t *videoram;
83,10 → 81,10
 
static void ega_move_cursor(void)
{
outb(ega_base + EGA_INDEX_REG, 0xe);
outb(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff));
outb(ega_base + EGA_INDEX_REG, 0xf);
outb(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff));
pio_write_8(ega_base + EGA_INDEX_REG, 0xe);
pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff));
pio_write_8(ega_base + EGA_INDEX_REG, 0xf);
pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff));
}
 
static void ega_display_char(char ch, bool silent)
152,12 → 150,6
chardev_initialize("ega_out", &ega_console, &ega_ops);
stdout = &ega_console;
ega_parea.pbase = videoram_phys;
ega_parea.vbase = (uintptr_t) videoram;
ega_parea.frames = 1;
ega_parea.cacheable = false;
ddi_parea_register(&ega_parea);
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 2);
sysinfo_set_item_val("fb.width", NULL, ROW);
/branches/dynload/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,9 → 38,9
#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
 
typedef struct {
uintptr_t addr;
63,14 → 63,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/dynload/kernel/generic/include/proc/program.h
59,8 → 59,7
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,
char *uspace_name, size_t name_len);
extern unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len);
 
#endif
 
/branches/dynload/kernel/generic/include/ddi/irq.h
79,10 → 79,10
} 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 *arg, inr_t inr);
typedef void (* cir_t)(void *, inr_t);
 
/** IPC notification config structure.
*
139,11 → 139,11
/** Trigger level of the IRQ. */
irq_trigger_t trigger;
/** Claim ownership of the IRQ. */
irq_ownership_t (* claim)(void);
irq_ownership_t (* claim)(void *);
/** 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;
154,11 → 154,11
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);
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);
extern irq_t *irq_find_and_lock(inr_t, devno_t);
 
#endif
 
/branches/dynload/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/dynload/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);
/branches/dynload/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,7 → 59,9
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);
extern void hw_area(uintptr_t *physaddr, pfn_t *frames);
 
#endif
 
/branches/dynload/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
37,44 → 37,47
 
#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 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 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)))
 
/** 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));
}
 
/* 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
*
/branches/dynload/kernel/generic/src/time/clock.c
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);
 
/*
/branches/dynload/kernel/generic/src/ddi/ddi.c
47,7 → 47,7
#include <mm/as.h>
#include <synch/spinlock.h>
#include <syscall/copy.h>
#include <adt/btree.h>
#include <adt/list.h>
#include <arch.h>
#include <align.h>
#include <errno.h>
55,13 → 55,17
/** This lock protects the parea_btree. */
SPINLOCK_INITIALIZE(parea_lock);
 
/** B+tree with enabled physical memory areas. */
static btree_t parea_btree;
/** List with enabled physical memory areas. */
static LIST_INITIALIZE(parea_head);
 
/** Physical memory area for devices. */
static parea_t dev_area;
 
/** Initialize DDI. */
void ddi_init(void)
{
btree_create(&parea_btree);
hw_area(&dev_area.pbase, &dev_area.frames);
ddi_parea_register(&dev_area);
}
 
/** Enable piece of physical memory for mapping by physmem_map().
74,19 → 78,19
void ddi_parea_register(parea_t *parea)
{
ipl_t ipl;
 
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.
* However, we should be safe because the kernel is pretty sane.
*/
btree_insert(&parea_btree, (btree_key_t) parea->pbase, parea, NULL);
 
link_initialize(&parea->link);
list_append(&parea->link, &parea_head);
spinlock_unlock(&parea_lock);
interrupts_restore(ipl);
interrupts_restore(ipl);
}
 
/** Map piece of physical memory into virtual address space of current task.
97,16 → 101,16
* @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, ENOENT if there is no task matching the specified ID or the
* physical address space is not enabled for mapping and ENOMEM if there
* was a problem in creating address space area.
*/
static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, count_t pages, int flags)
static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, pfn_t pages, int flags)
{
ipl_t ipl;
cap_t caps;
mem_backend_data_t backend_data;
 
backend_data.base = pf;
backend_data.frames = pages;
116,30 → 120,35
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)) {
bool fnd = false;
link_t *cur;
for (cur = parea_head.next; cur != &parea_head; cur = cur->next) {
parea_t *parea = list_get_instance(cur, parea_t, link);
if ((parea->pbase <= pf) && (ADDR2PFN(pf - parea->pbase) + pages <= parea->frames)) {
fnd = true;
break;
}
}
spinlock_unlock(&parea_lock);
if (!fnd) {
/*
* This physical memory area cannot be mapped.
* Physical memory area cannot be mapped.
*/
spinlock_unlock(&parea_lock);
interrupts_restore(ipl);
return ENOENT;
}
spinlock_unlock(&parea_lock);
 
spinlock_lock(&TASK->lock);
if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE,
226,7 → 235,7
{
return (unative_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base,
FRAME_SIZE), ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE),
(count_t) pages, (int) flags);
(pfn_t) pages, (int) flags);
}
 
/** Wrapper for SYS_ENABLE_IOSPACE syscall.
258,13 → 267,13
*/
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/dynload/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.
144,7 → 145,7
irq->trigger = (irq_trigger_t) 0;
irq->claim = NULL;
irq->handler = NULL;
irq->arg = NULL;
irq->instance = NULL;
irq->cir = NULL;
irq->cir_arg = NULL;
irq->notif_cfg.notify = false;
306,7 → 307,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->instance) == IRQ_ACCEPT));
} else {
/* Invoked by irq_find_and_lock(). */
rv = ((irq->inr == inr) && (irq->devno == devno));
365,7 → 367,7
spinlock_lock(&irq->lock);
if (devno == -1) {
/* Invoked by irq_dispatch_and_lock() */
rv = (irq->claim() == IRQ_ACCEPT);
rv = (irq->claim(irq->instance) == IRQ_ACCEPT);
} else {
/* Invoked by irq_find_and_lock() */
rv = (irq->devno == devno);
/branches/dynload/kernel/generic/src/console/console.c
101,7 → 101,7
*
* @return Always returns IRQ_DECLINE.
*/
static irq_ownership_t klog_claim(void)
static irq_ownership_t klog_claim(void *instance)
{
return IRQ_DECLINE;
}
126,9 → 126,7
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);
/branches/dynload/kernel/generic/src/console/cmd.c
529,7 → 529,7
spinlock_unlock(&hlp->lock);
}
spinlock_unlock(&cmd_lock);
spinlock_unlock(&cmd_lock);
 
return 1;
}
/branches/dynload/kernel/generic/src/console/kconsole.c
103,7 → 103,7
* @return Always returns IRQ_DECLINE.
*
*/
static irq_ownership_t kconsole_claim(void)
static irq_ownership_t kconsole_claim(void *instance)
{
return IRQ_DECLINE;
}
/branches/dynload/kernel/generic/src/proc/task.c
339,7 → 339,7
bool sleeping = false;
thr = list_get_instance(cur, thread_t, th_link);
spinlock_lock(&thr->lock);
thr->interrupted = true;
if (thr->state == Sleeping)
/branches/dynload/kernel/generic/src/proc/program.c
184,32 → 184,20
 
/** 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, char *uspace_name,
size_t name_len)
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;
 
/* 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 (rc != 0)
return rc;
 
/* Cap length of name and copy it from userspace. */
 
if (name_len > THREAD_NAME_BUFLEN - 1)
221,12 → 209,6
 
namebuf[name_len] = '\0';
 
/* Allocate the phone for communicating with the new task. */
 
phone_id = phone_alloc();
if (phone_id < 0)
return ELIMIT;
 
/* Spawn the new task. */
 
rc = program_create_loader(&p, namebuf);
233,18 → 215,6
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/dynload/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/dynload/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/dynload/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);
/branches/dynload/kernel/generic/src/ipc/irq.c
101,10 → 101,10
code->cmds[i].value;
break;
case CMD_PORT_READ_1:
dstval = inb((long) code->cmds[i].addr);
dstval = pio_read_8((long) code->cmds[i].addr);
break;
case CMD_PORT_WRITE_1:
outb((long) code->cmds[i].addr, code->cmds[i].value);
pio_write_8((long) code->cmds[i].addr, code->cmds[i].value);
break;
default:
break;
/branches/dynload/kernel/Makefile
246,7 → 246,6
test/atomic/atomic1.c \
test/btree/btree1.c \
test/avltree/avltree1.c \
test/debug/mips1.c \
test/fault/fault1.c \
test/mm/falloc1.c \
test/mm/falloc2.c \
253,7 → 252,6
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 \
265,19 → 263,34
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)
285,9 → 298,7
endif
endif
ifeq ($(TEST_FPU1),y)
GENERIC_SOURCES += test/fpu/fpu1.c
else
ifneq ($(TEST_FPU1),y)
GENERIC_SOURCES += test/fpu/fpu1_skip.c
endif
/branches/dynload/kernel/arch/sparc64/include/cpu_node.h
55,4 → 55,5
#endif
 
/** @}
*/
*/
 
/branches/dynload/kernel/arch/sparc64/include/arch.h
45,6 → 45,12
 
#define NWINDOWS 8 /** Number of register window sets. */
 
#ifndef __ASM__
 
extern void arch_pre_main(void);
 
#endif /* __ASM__ */
 
#endif
 
/** @}
/branches/dynload/kernel/arch/sparc64/include/asm.h
44,25 → 44,25
#include <arch/stack.h>
#include <arch/barrier.h>
 
static inline void outb(ioport_t port, uint8_t v)
static inline void pio_write_8(ioport_t port, uint8_t v)
{
*((volatile uint8_t *)(port)) = v;
memory_barrier();
}
 
static inline void outw(ioport_t port, uint16_t v)
static inline void pio_write_16(ioport_t port, uint16_t v)
{
*((volatile uint16_t *)(port)) = v;
memory_barrier();
}
 
static inline void outl(ioport_t port, uint32_t v)
static inline void pio_write_32(ioport_t port, uint32_t v)
{
*((volatile uint32_t *)(port)) = v;
memory_barrier();
}
 
static inline uint8_t inb(ioport_t port)
static inline uint8_t pio_read_8(ioport_t port)
{
uint8_t rv;
 
72,7 → 72,7
return rv;
}
 
static inline uint16_t inw(ioport_t port)
static inline uint16_t pio_read_16(ioport_t port)
{
uint16_t rv;
 
82,7 → 82,7
return rv;
}
 
static inline uint32_t inl(ioport_t port)
static inline uint32_t pio_read_32(ioport_t port)
{
uint32_t rv;
 
/branches/dynload/kernel/arch/sparc64/include/mm/frame.h
73,6 → 73,7
typedef union frame_address frame_address_t;
 
extern uintptr_t last_frame;
extern uintptr_t end_frame;
extern void frame_arch_init(void);
#define physmem_print()
 
/branches/dynload/kernel/arch/sparc64/include/cpu_family.h
79,4 → 79,5
#endif
 
/** @}
*/
*/
 
/branches/dynload/kernel/arch/sparc64/src/console.c
141,32 → 141,10
{
thread_detach(THREAD);
 
#ifdef CONFIG_Z8530
if (kbd_type == KBD_Z8530) {
/*
* The z8530 driver is interrupt-driven.
*/
if (kbd_type != KBD_SGCN)
return;
}
#endif
 
#ifdef CONFIG_NS16550
#ifdef CONFIG_NS16550_INTERRUPT_DRIVEN
if (kbd_type == KBD_NS16550) {
/*
* The ns16550 driver is interrupt-driven.
*/
return;
}
#endif
#endif
while (1) {
#ifdef CONFIG_NS16550
#ifndef CONFIG_NS16550_INTERRUPT_DRIVEN
if (kbd_type == KBD_NS16550)
ns16550_poll();
#endif
#endif
#ifdef CONFIG_SGCN
if (kbd_type == KBD_SGCN)
sgcn_poll();
/branches/dynload/kernel/arch/sparc64/src/sparc64.c
103,7 → 103,6
{
static thread_t *t = NULL;
 
 
if (!t) {
/*
* Create thread that polls keyboard.
/branches/dynload/kernel/arch/sparc64/src/trap/interrupt.c
86,7 → 86,7
/*
* The IRQ handler was found.
*/
irq->handler(irq, irq->arg);
irq->handler(irq);
/*
* See if there is a clear-interrupt-routine and call it.
*/
/branches/dynload/kernel/arch/sparc64/src/mm/frame.c
41,6 → 41,7
#include <macros.h>
 
uintptr_t last_frame = NULL;
uintptr_t end_frame = NULL;
 
/** Create memory zones according to information stored in bootinfo.
*
80,6 → 81,7
frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1);
}
end_frame = last_frame;
}
 
/** @}
/branches/dynload/kernel/arch/sparc64/src/mm/page.c
147,7 → 147,7
physaddr + i * sizemap[order].increment,
sizemap[order].pagesize_code, true, false);
#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
/*
* Second, save the information about the mapping for APs.
*/
164,6 → 164,11
return virtaddr;
}
 
void hw_area(uintptr_t *physaddr, pfn_t *frames)
{
*physaddr = end_frame;
*frames = ADDR2PFN(0x7ffffffffff - end_frame);
}
 
/** @}
*/
 
/branches/dynload/kernel/arch/sparc64/src/drivers/sgcn.c
161,19 → 161,10
chardev_t sgcn_io;
 
/**
* Registers the physical area of the SRAM so that the userspace SGCN
* driver can map it. Moreover, it sets some sysinfo values (SRAM address
* and SRAM size).
* Set some sysinfo values (SRAM address and SRAM size).
*/
static void register_sram_parea(uintptr_t sram_begin_physical)
static void register_sram(uintptr_t sram_begin_physical)
{
static parea_t sram_parea;
sram_parea.pbase = sram_begin_physical;
sram_parea.vbase = (uintptr_t) sram_begin;
sram_parea.frames = MAPPED_AREA_SIZE / FRAME_SIZE;
sram_parea.cacheable = false;
ddi_parea_register(&sram_parea);
sysinfo_set_item_val("sram.area.size", NULL, MAPPED_AREA_SIZE);
sysinfo_set_item_val("sram.address.physical", NULL,
sram_begin_physical);
211,7 → 202,7
+ *((uint32_t *) iosram_toc->value);
sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE);
register_sram_parea(sram_begin_physical);
register_sram(sram_begin_physical);
}
 
/**
319,7 → 310,7
/**
* The driver works in polled mode, so no interrupt should be handled by it.
*/
static irq_ownership_t sgcn_claim(void)
static irq_ownership_t sgcn_claim(void *instance)
{
return IRQ_DECLINE;
}
327,7 → 318,7
/**
* The driver works in polled mode, so no interrupt should be handled by it.
*/
static void sgcn_irq_handler(irq_t *irq, void *arg, ...)
static void sgcn_irq_handler(irq_t *irq)
{
panic("Not yet implemented, SGCN works in polled mode.");
}
/branches/dynload/kernel/arch/ia64/include/arch.h
39,6 → 39,8
 
#include <arch/ski/ski.h>
 
extern void arch_pre_main(void);
 
#endif
 
/** @}
/branches/dynload/kernel/arch/ia64/include/asm.h
41,7 → 41,7
 
#define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL
 
static inline void outb(ioport_t port, uint8_t v)
static inline void pio_write_8(ioport_t port, uint8_t v)
{
*((uint8_t *)(IA64_IOSPACE_ADDRESS +
((port & 0xfff) | ((port >> 2) << 12)))) = v;
49,7 → 49,7
asm volatile ("mf\n" ::: "memory");
}
 
static inline void outw(ioport_t port, uint16_t v)
static inline void pio_write_16(ioport_t port, uint16_t v)
{
*((uint16_t *)(IA64_IOSPACE_ADDRESS +
((port & 0xfff) | ((port >> 2) << 12)))) = v;
57,7 → 57,7
asm volatile ("mf\n" ::: "memory");
}
 
static inline void outl(ioport_t port, uint32_t v)
static inline void pio_write_32(ioport_t port, uint32_t v)
{
*((uint32_t *)(IA64_IOSPACE_ADDRESS +
((port & 0xfff) | ((port >> 2) << 12)))) = v;
65,7 → 65,7
asm volatile ("mf\n" ::: "memory");
}
 
static inline uint8_t inb(ioport_t port)
static inline uint8_t pio_read_8(ioport_t port)
{
asm volatile ("mf\n" ::: "memory");
 
73,7 → 73,7
((port & 0xfff) | ((port >> 2) << 12))));
}
 
static inline uint16_t inw(ioport_t port)
static inline uint16_t pio_read_16(ioport_t port)
{
asm volatile ("mf\n" ::: "memory");
 
81,7 → 81,7
((port & 0xffE) | ((port >> 2) << 12))));
}
 
static inline uint32_t inl(ioport_t port)
static inline uint32_t pio_read_32(ioport_t port)
{
asm volatile ("mf\n" ::: "memory");
 
/branches/dynload/kernel/arch/ia64/include/mm/frame.h
44,6 → 44,7
#include <arch/types.h>
 
extern uintptr_t last_frame;
extern uintptr_t end_frame;
 
extern void frame_arch_init(void);
#define physmem_print()
/branches/dynload/kernel/arch/ia64/include/drivers/i8042.h
47,22 → 47,22
 
static inline void i8042_data_write(uint8_t data)
{
outb(i8042_DATA, data);
pio_write_8(i8042_DATA, data);
}
 
static inline uint8_t i8042_data_read(void)
{
return inb(i8042_DATA);
return pio_read_8(i8042_DATA);
}
 
static inline uint8_t i8042_status_read(void)
{
return inb(i8042_STATUS);
return pio_read_8(i8042_STATUS);
}
 
static inline void i8042_command_write(uint8_t command)
{
outb(i8042_STATUS, command);
pio_write_8(i8042_STATUS, command);
}
 
#endif
/branches/dynload/kernel/arch/ia64/src/ia64.c
148,36 → 148,13
{
}
 
 
#ifdef I460GX
#define POLL_INTERVAL 50000 /* 50 ms */
/** Kernel thread for polling keyboard. */
static void i8042_kkbdpoll(void *arg)
{
while (1) {
#ifdef CONFIG_NS16550
#ifndef CONFIG_NS16550_INTERRUPT_DRIVEN
ns16550_poll();
#endif
#else
#ifndef CONFIG_I8042_INTERRUPT_DRIVEN
i8042_poll();
#endif
#endif
thread_usleep(POLL_INTERVAL);
}
}
#endif
 
void arch_post_smp_init(void)
{
thread_t *t;
 
/*
* Create thread that polls keyboard.
*/
#ifdef SKI
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("Cannot create kkbdpoll.");
thread_ready(t);
192,10 → 169,6
devno_t mouse = device_assign_devno();
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE);
#endif
t = thread_create(i8042_kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("Cannot create kkbdpoll.");
thread_ready(t);
#endif
 
sysinfo_set_item_val("ia64_iospace", NULL, true);
276,7 → 249,7
 
void arch_reboot(void)
{
outb(0x64, 0xfe);
pio_write_8(0x64, 0xfe);
while (1)
;
}
/branches/dynload/kernel/arch/ia64/src/ski/ski.c
186,7 → 186,7
*
* @return Always IRQ_DECLINE.
*/
static irq_ownership_t ski_kbd_claim(void)
static irq_ownership_t ski_kbd_claim(void *instance)
{
return IRQ_DECLINE;
}
/branches/dynload/kernel/arch/ia64/src/mm/frame.c
51,6 → 51,7
#define MINCONF 1
 
uintptr_t last_frame = 0;
uintptr_t end_frame = 0;
 
void frame_arch_init(void)
{
/branches/dynload/kernel/arch/ia64/src/mm/page.c
274,5 → 274,11
return PA2KA(physaddr);
}
 
void hw_area(uintptr_t *physaddr, pfn_t *frames)
{
*physaddr = end_frame;
*frames = ADDR2PFN(0x7fffffffffffffffUL - end_frame);
}
 
/** @}
*/
/branches/dynload/kernel/arch/ia64/src/interrupt.c
266,7 → 266,7
case INTERRUPT_TIMER:
irq = irq_dispatch_and_lock(ivr.vector);
if (irq) {
irq->handler(irq, irq->arg);
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
panic("Unhandled Internal Timer Interrupt (%d).",
283,7 → 283,7
/* Send EOI before processing the interrupt */
end_of_local_irq();
}
irq->handler(irq, irq->arg);
irq->handler(irq);
if (!irq->preack)
end_of_local_irq();
spinlock_unlock(&irq->lock);
/branches/dynload/kernel/arch/ia64/src/drivers/it.c
56,8 → 56,8
 
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(void *);
static void it_interrupt(irq_t *irq);
 
/** Initialize Interval Timer. */
void it_init(void)
104,13 → 104,13
*
* @return Always IRQ_ACCEPT.
*/
irq_ownership_t it_claim(void)
irq_ownership_t it_claim(void *instance)
{
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/dynload/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/dynload/kernel/arch/arm32/include/boot.h
File deleted
/branches/dynload/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
39,24 → 39,7
/** Size of a temporary stack used for initial kernel start. */
#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/dynload/kernel/arch/arm32/include/machine.h
102,7 → 102,7
extern uintptr_t machine_get_fb_address(void);
 
 
#ifdef MACHINE_GXEMUL_TESTARM
#ifdef MACHINE_gxemul
#define machine_console_init(devno) gxemul_console_init(devno)
#define machine_grab_console gxemul_grab_console
#define machine_release_console gxemul_release_console
/branches/dynload/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,23
#ifndef KERN_arm32_ARCH_H_
#define KERN_arm32_ARCH_H_
 
#define TASKMAP_MAX_RECORDS 32
#define CPUMAP_MAX_RECORDS 32
 
#include <typedefs.h>
 
typedef struct {
uintptr_t addr;
uint32_t size;
} 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/dynload/kernel/arch/arm32/include/asm.h
46,15 → 46,14
{
}
 
/** No I/O port address space on ARM. */
static inline void outb(ioport_t port, uint8_t v)
static inline void pio_write_8(ioport_t port, uint8_t v)
{
/* XXX */
}
 
/** No I/O port address space on ARM. */
static inline uint8_t inb(ioport_t port)
static inline uint8_t pio_read_8(ioport_t port)
{
return 0;
return 0; /* XXX */
}
 
/** Return base address of current stack.
/branches/dynload/kernel/arch/arm32/include/mm/frame.h
51,6 → 51,7
#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH)
 
extern uintptr_t last_frame;
extern uintptr_t end_frame;
 
extern void frame_arch_init(void);
extern void boot_page_table_free(void);
/branches/dynload/kernel/arch/arm32/Makefile.inc
35,14 → 35,11
TARGET = arm-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm
 
KERNEL_LOAD_ADDRESS = 0x80200000
DMACHINE = MACHINE_GXEMUL_TESTARM
 
ATSIGN = %
 
GCC_CFLAGS += -fno-zero-initialized-in-bss
 
DEFS += -D__32_BITS__ -DKERNEL_LOAD_ADDRESS=$(KERNEL_LOAD_ADDRESS) -D$(DMACHINE)
DEFS += -D__32_BITS__
 
ARCH_SOURCES = \
arch/$(KARCH)/src/start.S \
/branches/dynload/kernel/arch/arm32/src/arm32.c
34,7 → 34,6
*/
 
#include <arch.h>
#include <arch/boot.h>
#include <config.h>
#include <arch/console.h>
#include <ddi/device.h>
48,22 → 47,19
#include <arch/regutils.h>
#include <arch/machine.h>
#include <userspace.h>
#include <macros.h>
 
/** Information about loaded tasks. */
bootinfo_t bootinfo;
 
/** Performs arm32 specific initialization before main_bsp() is called. */
void arch_pre_main(void)
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;
}
}
 
/** Performs arm32 specific initialization before mm is initialized. */
/branches/dynload/kernel/arch/arm32/src/mm/frame.c
41,6 → 41,7
 
/** Address of the last frame in the memory. */
uintptr_t last_frame = 0;
uintptr_t end_frame = 0;
 
/** Creates memory zones. */
void frame_arch_init(void)
49,7 → 50,8
zone_create(0, ADDR2PFN(machine_get_memory_size()),
BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0);
last_frame = machine_get_memory_size();
 
end_frame = last_frame;
/* blacklist boot page table */
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME,
BOOT_PAGE_TABLE_SIZE_IN_FRAMES);
/branches/dynload/kernel/arch/arm32/src/mm/page.c
106,5 → 106,11
return virtaddr;
}
 
void hw_area(uintptr_t *physaddr, pfn_t *frames)
{
*physaddr = end_frame;
*frames = ADDR2PFN(0xffffffff - end_frame);
}
 
/** @}
*/
/branches/dynload/kernel/arch/arm32/src/drivers/gxemul.c
184,9 → 184,8
/** Process keyboard interrupt.
*
* @param irq IRQ information.
* @param arg Not used.
*/
static void gxemul_irq_handler(irq_t *irq, void *arg, ...)
static void gxemul_irq_handler(irq_t *irq)
{
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) {
ipc_irq_send_notif(irq);
204,7 → 203,7
}
}
 
static irq_ownership_t gxemul_claim(void)
static irq_ownership_t gxemul_claim(void *instance)
{
return IRQ_ACCEPT;
}
266,7 → 265,7
*((uint32_t*) gxemul_hw_map.rtc_freq) = frequency;
}
 
static irq_ownership_t gxemul_timer_claim(void)
static irq_ownership_t gxemul_timer_claim(void *instance)
{
return IRQ_ACCEPT;
}
276,7 → 275,7
* @param irq Interrupt information.
* @param arg Not used.
*/
static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...)
static void gxemul_timer_irq_handler(irq_t *irq)
{
/*
* We are holding a lock which prevents preemption.
370,7 → 369,7
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq, irq->arg);
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
/branches/dynload/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/dynload/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/dynload/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,13 → 35,13
#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__
 
/branches/dynload/kernel/arch/ppc32/include/asm.h
149,15 → 149,14
 
extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry);
 
/** No I/O port address space on PowerPC. */
static inline void outb(ioport_t port, uint8_t v)
static inline void pio_write_8(ioport_t port, uint8_t v)
{
/* XXX */
}
 
/** No I/O port address space on PowerPC. */
static inline uint8_t inb(ioport_t port)
static inline uint8_t pio_read_8(ioport_t port)
{
return 0;
return 0; /* XXX */
}
 
#endif
/branches/dynload/kernel/arch/ppc32/include/mm/frame.h
41,9 → 41,10
#ifdef KERNEL
#ifndef __ASM__
 
#include <arch/types.h>
#include <arch/types.h>
 
extern uintptr_t last_frame;
extern uintptr_t end_frame;
 
extern void frame_arch_init(void);
extern void physmem_print(void);
/branches/dynload/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/dynload/kernel/arch/ppc32/src/ppc32.c
45,19 → 45,19
#include <ddi/device.h>
#include <ddi/irq.h>
#include <arch/drivers/pic.h>
#include <macros.h>
 
#define IRQ_COUNT 64
#define IRQ_COUNT 64
 
bootinfo_t bootinfo;
 
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;
}
/branches/dynload/kernel/arch/ppc32/src/mm/frame.c
40,6 → 40,7
#include <print.h>
 
uintptr_t last_frame = 0;
uintptr_t end_frame = 0;
 
void physmem_print(void)
{
74,7 → 75,9
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);
}
 
end_frame = last_frame;
/* First is exception vector, second is 'implementation specific',
third and fourth is reserved, other contain real mode code */
frame_mark_unavailable(0, 8);
/branches/dynload/kernel/arch/ppc32/src/mm/page.c
63,5 → 63,11
return virtaddr;
}
 
void hw_area(uintptr_t *physaddr, pfn_t *frames)
{
*physaddr = end_frame;
*frames = ADDR2PFN(0xffffffff - end_frame);
}
 
/** @}
*/
/branches/dynload/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 {
/*
/branches/dynload/kernel/arch/ppc32/src/drivers/cuda.c
249,7 → 249,7
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);
264,7 → 264,7
}
}
 
static irq_ownership_t cuda_claim(void)
static irq_ownership_t cuda_claim(void *instance)
{
return IRQ_ACCEPT;
}
/branches/dynload/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/dynload/kernel/arch/amd64/include/asm.h
73,7 → 73,7
* @param port Port to read from
* @return Value read
*/
static inline uint8_t inb(uint16_t port)
static inline uint8_t pio_read_8(uint16_t port)
{
uint8_t val;
 
88,7 → 88,7
* @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(uint16_t port, uint8_t val)
{
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port));
}
/branches/dynload/kernel/arch/amd64/include/mm/frame.h
44,6 → 44,7
 
#ifndef __ASM__
extern uintptr_t last_frame;
extern uintptr_t end_frame;
extern void frame_arch_init(void);
extern void physmem_print(void);
#endif /* __ASM__ */
/branches/dynload/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/dynload/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/dynload/kernel/arch/amd64/src/debugger.c
64,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
101,7 → 99,6
.argv = &addw_argv
};
 
#endif /* CONFIG_DEBUG_AS_WATCHPOINT */
#endif /* CONFIG_KCONSOLE */
 
/* Setup DR register according to table */
320,7 → 317,6
if (!cmd_register(&bkpts_info))
printf("Cannot register command %s\n", bkpts_info.name);
 
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
cmd_initialize(&delbkpt_info);
if (!cmd_register(&delbkpt_info))
printf("Cannot register command %s\n", delbkpt_info.name);
332,7 → 328,6
cmd_initialize(&addwatchp_info);
if (!cmd_register(&addwatchp_info))
printf("Cannot register command %s\n", addwatchp_info.name);
#endif /* CONFIG_DEBUG_AS_WATCHPOINT */
#endif /* CONFIG_KCONSOLE */
exc_register(VECTOR_DEBUG, "debugger", debug_exception);
378,8 → 373,6
return 1;
}
 
#ifndef CONFIG_DEBUG_AS_WATCHPOINT
 
/** Remove breakpoint from table */
int cmd_del_breakpoint(cmd_arg_t *argv)
{
412,7 → 405,6
return 1;
}
#endif /* CONFIG_DEBUG_AS_WATCHPOINT */
#endif /* CONFIG_KCONSOLE */
 
/** @}
/branches/dynload/kernel/arch/amd64/src/mm/page.c
214,5 → 214,11
return virtaddr;
}
 
void hw_area(uintptr_t *physaddr, pfn_t *frames)
{
*physaddr = end_frame;
*frames = ADDR2PFN(0xfffffffffffff - end_frame);
}
 
/** @}
*/
/branches/dynload/kernel/arch/amd64/src/interrupt.c
80,12 → 80,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]);
}
 
179,7 → 173,7
trap_virtual_eoi();
ack = true;
}
irq->handler(irq, irq->arg);
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/*
/branches/dynload/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/dynload/kernel/arch/mips32/include/boot.h
File deleted
/branches/dynload/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/dynload/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__
 
/branches/dynload/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/dynload/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/dynload/kernel/arch/mips32/include/smp/order.h
File deleted
/branches/dynload/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/dynload/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/dynload/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,26
#ifndef KERN_mips32_ARCH_H_
#define KERN_mips32_ARCH_H_
 
#define TASKMAP_MAX_RECORDS 32
#define CPUMAP_MAX_RECORDS 32
 
#include <typedefs.h>
 
extern count_t cpu_count;
 
typedef struct {
uintptr_t addr;
uint32_t size;
} 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/dynload/kernel/arch/mips32/include/asm.h
55,7 → 55,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,22 → 67,22
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);
 
/** No I/O port address space on MIPS. */
static inline void outb(ioport_t port, uint8_t v)
static inline void pio_write_8(ioport_t port, uint8_t v)
{
/* XXX */
}
 
/** No I/O port address space on MIPS. */
static inline uint8_t inb(ioport_t port)
static inline uint8_t pio_read_8(ioport_t port)
{
return 0;
return 0; /* XXX */
}
 
#endif
/branches/dynload/kernel/arch/mips32/include/mm/frame.h
35,15 → 35,19
#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);
 
extern uintptr_t end_frame;
 
#endif /* __ASM__ */
#endif /* KERNEL */
 
/branches/dynload/kernel/arch/mips32/include/cpu.h
42,7 → 42,7
uint32_t imp_num;
uint32_t rev_num;
} cpu_arch_t;
 
#endif
 
/** @}
/branches/dynload/kernel/arch/mips32/Makefile.inc
33,11 → 33,9
TARGET = mipsel-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel
 
KERNEL_LOAD_ADDRESS = 0x80100000
 
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss
 
DEFS += -D__32_BITS__ -D$(MACHINE) -DKERNEL_LOAD_ADDRESS=$(KERNEL_LOAD_ADDRESS)
DEFS += -D__32_BITS__
 
## Accepted MACHINEs
#
74,7 → 72,6
arch/$(KARCH)/src/context.S \
arch/$(KARCH)/src/panic.S \
arch/$(KARCH)/src/mips32.c \
arch/$(KARCH)/src/dummy.S \
arch/$(KARCH)/src/console.c \
arch/$(KARCH)/src/asm.S \
arch/$(KARCH)/src/exception.c \
90,4 → 87,5
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/drivers/msim.c \
arch/$(KARCH)/src/drivers/serial.c \
arch/$(KARCH)/src/smp/order.c
arch/$(KARCH)/src/smp/dorder.c \
arch/$(KARCH)/src/smp/smp.c
/branches/dynload/kernel/arch/mips32/src/dummy.S
File deleted
/branches/dynload/kernel/arch/mips32/src/exception.c
144,7 → 144,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)) {
153,7 → 153,7
/*
* The IRQ handler was found.
*/
irq->handler(irq, irq->arg);
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/*
160,7 → 160,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
}
}
/branches/dynload/kernel/arch/mips32/src/asm.S
27,7 → 27,7
#
 
#include <arch/asm/regname.h>
 
.text
 
.macro cp0_read reg
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
/branches/dynload/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/dynload/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>
58,34 → 57,39
 
#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;
 
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;
}
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++;
}
}
 
137,19 → 141,19
fb_init(&gxemul_prop);
#endif
 
#ifdef msim
#ifdef MACHINE_msim
sysinfo_set_item_val("machine.msim", NULL, 1);
#endif
 
#ifdef simics
#ifdef MACHINE_simics
sysinfo_set_item_val("machine.simics", NULL, 1);
#endif
 
#ifdef bgxemul
#ifdef MACHINE_bgxemul
sysinfo_set_item_val("machine.bgxemul", NULL, 1);
#endif
 
#ifdef lgxemul
#ifdef MACHINE_lgxemul
sysinfo_set_item_val("machine.lgxemul", NULL, 1);
#endif
}
166,6 → 170,10
{
}
 
void calibrate_delay_loop(void)
{
}
 
void userspace(uspace_arg_t *kernel_uarg)
{
/* EXL = 1, UM = 1, IE = 1 */
/branches/dynload/kernel/arch/mips32/src/smp/order.c
File deleted
/branches/dynload/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/dynload/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/dynload/kernel/arch/mips32/src/debugger.c
162,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 ==
169,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++)
/branches/dynload/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
41,7 → 41,7
#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>
92,15 → 92,15
uintptr_t badvaddr;
pte_t *pte;
int pfrc;
 
badvaddr = cp0_badvaddr_read();
 
spinlock_lock(&AS->lock);
mutex_lock(&AS->lock);
asid = AS->asid;
spinlock_unlock(&AS->lock);
 
mutex_unlock(&AS->lock);
page_table_lock(AS, true);
 
pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc);
if (!pte) {
switch (pfrc) {
/branches/dynload/kernel/arch/mips32/src/mm/frame.c
65,7 → 65,9
static count_t phys_regions_count = 0;
static phys_region_t phys_regions[MAX_REGIONS];
 
uintptr_t end_frame = 0;
 
 
/** Check whether frame is available
*
* Returns true if given frame is generally available for use.
75,7 → 77,7
*/
static bool frame_available(pfn_t frame)
{
#ifdef msim
#ifdef MACHINE_msim
/* MSIM device (dprinter) */
if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH))
return false;
85,13 → 87,13
return false;
#endif
 
#ifdef simics
#ifdef MACHINE_simics
/* Simics device (serial line) */
if (frame == (KA2PA(SERIAL_ADDRESS) >> ZERO_PAGE_WIDTH))
return false;
#endif
 
#if defined(lgxemul) || defined(bgxemul)
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)
/* gxemul devices */
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
0x10000000, MB2SIZE(256)))
236,8 → 238,10
}
}
frame_add_region(start_frame, frame);
end_frame = frame;
frame_add_region(start_frame, end_frame);
/* Blacklist interrupt vector frame */
frame_mark_unavailable(0, 1);
/branches/dynload/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)
{
50,5 → 51,11
return physaddr + 0xa0000000;
}
 
void hw_area(uintptr_t *physaddr, pfn_t *frames)
{
*physaddr = end_frame;
*frames = ADDR2PFN(0xffffffff - end_frame);
}
 
/** @}
*/
/branches/dynload/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(void *instance)
{
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/dynload/kernel/arch/mips32/src/drivers/serial.c
112,7 → 112,7
}
 
/** Process keyboard interrupt. Does not work in simics? */
static void serial_irq_handler(irq_t *irq, void *arg, ...)
static void serial_irq_handler(irq_t *irq)
{
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox))
ipc_irq_send_notif(irq);
120,7 → 120,7
serial_handler();
}
 
static irq_ownership_t serial_claim(void)
static irq_ownership_t serial_claim(void *instance)
{
return IRQ_ACCEPT;
}
/branches/dynload/kernel/arch/mips32/src/drivers/msim.c
41,7 → 41,6
#include <sysinfo/sysinfo.h>
#include <ddi/ddi.h>
 
static parea_t msim_parea;
static chardev_t console;
static irq_t msim_irq;
 
94,7 → 93,7
}
 
/** Process keyboard interrupt. */
static void msim_irq_handler(irq_t *irq, void *arg, ...)
static void msim_irq_handler(irq_t *irq)
{
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox))
ipc_irq_send_notif(irq);
110,7 → 109,7
}
}
 
static irq_ownership_t msim_claim(void)
static irq_ownership_t msim_claim(void *instance)
{
return IRQ_ACCEPT;
}
156,12 → 155,6
sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS);
msim_parea.pbase = KA2PA(MSIM_VIDEORAM);
msim_parea.vbase = MSIM_VIDEORAM;
msim_parea.frames = 1;
msim_parea.cacheable = false;
ddi_parea_register(&msim_parea);
sysinfo_set_item_val("fb", NULL, true);
sysinfo_set_item_val("fb.kind", NULL, 3);
sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(MSIM_VIDEORAM));
/branches/dynload/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/dynload/kernel/arch/ia32/include/asm.h
105,7 → 105,7
* @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(uint16_t port, uint8_t val)
{
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) );
}
117,7 → 117,7
* @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(uint16_t port, uint16_t val)
{
asm volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) );
}
129,7 → 129,7
* @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(uint16_t port, uint32_t val)
{
asm volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) );
}
141,7 → 141,7
* @param port Port to read from
* @return Value read
*/
static inline uint8_t inb(uint16_t port)
static inline uint8_t pio_read_8(uint16_t port)
{
uint8_t val;
156,7 → 156,7
* @param port Port to read from
* @return Value read
*/
static inline uint16_t inw(uint16_t port)
static inline uint16_t pio_read_16(uint16_t port)
{
uint16_t val;
171,7 → 171,7
* @param port Port to read from
* @return Value read
*/
static inline uint32_t inl(uint16_t port)
static inline uint32_t pio_read_32(uint16_t port)
{
uint32_t val;
/branches/dynload/kernel/arch/ia32/include/mm/frame.h
44,6 → 44,7
#include <arch/types.h>
 
extern uintptr_t last_frame;
extern uintptr_t end_frame;
 
extern void frame_arch_init(void);
extern void physmem_print(void);
/branches/dynload/kernel/arch/ia32/include/barrier.h
69,7 → 69,7
#endif
}
 
#ifdef CONFIG_FENCES_P4
#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
77,7 → 77,7
# else
# define write_barrier() asm volatile( "" ::: "memory");
# endif
#elif CONFIG_FENCES_P3
#elif defined(CONFIG_FENCES_P3)
# define memory_barrier() cpuid_serialization()
# define read_barrier() cpuid_serialization()
# ifdef CONFIG_WEAK_MEMORY
/branches/dynload/kernel/arch/ia32/include/drivers/i8042.h
47,22 → 47,22
 
static inline void i8042_data_write(uint8_t data)
{
outb(i8042_DATA, data);
pio_write_8(i8042_DATA, data);
}
 
static inline uint8_t i8042_data_read(void)
{
return inb(i8042_DATA);
return pio_read_8(i8042_DATA);
}
 
static inline uint8_t i8042_status_read(void)
{
return inb(i8042_STATUS);
return pio_read_8(i8042_STATUS);
}
 
static inline void i8042_command_write(uint8_t command)
{
outb(i8042_STATUS, command);
pio_write_8(i8042_STATUS, command);
}
 
#endif
/branches/dynload/kernel/arch/ia32/src/asm.S
268,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
297,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/dynload/kernel/arch/ia32/src/smp/smp.c
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(0x70, 0xf);
pio_write_8(0x71, 0xa);
 
pic_disable_irqs(0xffff);
apic_init();
/branches/dynload/kernel/arch/ia32/src/smp/apic.c
132,12 → 132,12
#endif
}
 
static irq_ownership_t l_apic_timer_claim(void)
static irq_ownership_t l_apic_timer_claim(void *instance)
{
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/dynload/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>
70,15 → 69,6
 
/* 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/dynload/kernel/arch/ia32/src/mm/frame.c
50,6 → 50,7
size_t hardcoded_unmapped_kdata_size = 0;
 
uintptr_t last_frame = 0;
uintptr_t end_frame = 0;
 
static void init_e820_memory(pfn_t minconf)
{
73,8 → 74,10
e820table[i].size, FRAME_SIZE))
last_frame =
ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE);
}
}
}
end_frame = last_frame;
}
 
static char *e820names[] = {
113,16 → 116,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 → 132,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/dynload/kernel/arch/ia32/src/mm/page.c
93,6 → 93,12
return virtaddr;
}
 
void hw_area(uintptr_t *physaddr, pfn_t *frames)
{
*physaddr = end_frame;
*frames = ADDR2PFN(0xffffffff - end_frame);
}
 
void page_fault(int n __attribute__((unused)), istate_t *istate)
{
uintptr_t page;
102,7 → 108,7
if (istate->error_word & PFERR_CODE_RSVD)
panic("Reserved bit set in page directory.");
 
if (istate->error_word & PFERR_CODE_RW)
access = PF_ACCESS_WRITE;
else
/branches/dynload/kernel/arch/ia32/src/interrupt.c
77,9 → 77,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]);
}
191,7 → 188,7
trap_virtual_eoi();
ack = true;
}
irq->handler(irq, irq->arg);
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/*
/branches/dynload/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(0x20, 0x20);
pio_write_8(0xa0, 0x20);
}
 
void pic_spurious(int n __attribute__((unused)), istate_t *istate __attribute__((unused)))
/branches/dynload/kernel/arch/ia32/src/drivers/i8254.c
61,12 → 61,12
 
static irq_t i8254_irq;
 
static irq_ownership_t i8254_claim(void)
static irq_ownership_t i8254_claim(void *instance)
{
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)) +