Subversion Repositories HelenOS

Compare Revisions

No changes between revisions

Ignore whitespace Rev 4345 → Rev 4346

/branches/dynload/kernel/arch/sparc64/include/drivers/sgcn.h
36,6 → 36,7
#define KERN_sparc64_SGCN_H_
 
#include <arch/types.h>
#include <console/chardev.h>
 
/* number of bytes in the TOC magic, including the terminating '\0' */
#define TOC_MAGIC_BYTES 8
117,8 → 118,8
 
void sgcn_grab(void);
void sgcn_release(void);
void sgcn_poll(void);
void sgcn_init(void);
indev_t *sgcnin_init(void);
void sgcnout_init(void);
 
#endif
 
/branches/dynload/kernel/arch/sparc64/Makefile.inc
42,11 → 42,11
 
DEFS += -D__64_BITS__
 
ifeq ($(MACHINE),us)
ifeq ($(PROCESSOR),us)
DEFS += -DUS
endif
 
ifeq ($(MACHINE),us3)
ifeq ($(PROCESSOR),us3)
DEFS += -DUS3
endif
 
76,7 → 76,8
arch/$(KARCH)/src/drivers/tick.c \
arch/$(KARCH)/src/drivers/kbd.c \
arch/$(KARCH)/src/drivers/sgcn.c \
arch/$(KARCH)/src/drivers/pci.c
arch/$(KARCH)/src/drivers/pci.c \
arch/$(KARCH)/src/drivers/fhc.c
 
ifeq ($(CONFIG_FB),y)
ARCH_SOURCES += \
93,8 → 94,3
ARCH_SOURCES += \
arch/$(KARCH)/src/mm/tsb.c
endif
 
ifdef CONFIG_Z8530
ARCH_SOURCES += \
arch/$(KARCH)/src/drivers/fhc.c
endif
/branches/dynload/kernel/arch/sparc64/src/console.c
37,16 → 37,8
 
#include <arch/drivers/scr.h>
#include <arch/drivers/kbd.h>
 
#include <arch/drivers/sgcn.h>
 
#ifdef CONFIG_Z8530
#include <genarch/kbd/z8530.h>
#endif
#ifdef CONFIG_NS16550
#include <genarch/kbd/ns16550.h>
#endif
 
#include <genarch/srln/srln.h>
#include <console/chardev.h>
#include <console/console.h>
#include <arch/asm.h>
70,36 → 62,29
static void standard_console_init(ofw_tree_node_t *aliases)
{
#ifdef CONFIG_FB
stdin = NULL;
 
ofw_tree_property_t *prop;
ofw_tree_node_t *screen;
ofw_tree_node_t *keyboard;
prop = ofw_tree_getprop(aliases, "screen");
if (!prop)
ofw_tree_property_t *prop_scr = ofw_tree_getprop(aliases, "screen");
if (!prop_scr)
panic("Cannot find property 'screen'.");
if (!prop->value)
if (!prop_scr->value)
panic("Cannot find screen alias.");
screen = ofw_tree_lookup(prop->value);
ofw_tree_node_t *screen = ofw_tree_lookup(prop_scr->value);
if (!screen)
panic("Cannot find %s.", prop->value);
 
panic("Cannot find %s.", prop_scr->value);
scr_init(screen);
#endif
 
prop = ofw_tree_getprop(aliases, "keyboard");
if (!prop)
#ifdef CONFIG_SUN_KBD
ofw_tree_property_t *prop_kbd = ofw_tree_getprop(aliases, "keyboard");
if (!prop_kbd)
panic("Cannot find property 'keyboard'.");
if (!prop->value)
if (!prop_kbd->value)
panic("Cannot find keyboard alias.");
keyboard = ofw_tree_lookup(prop->value);
ofw_tree_node_t *keyboard = ofw_tree_lookup(prop_kbd->value);
if (!keyboard)
panic("Cannot find %s.", prop->value);
 
panic("Cannot find %s.", prop_kbd->value);
kbd_init(keyboard);
#else
panic("Standard console requires FB, "
"but the kernel is not compiled with FB support.");
#endif
}
 
106,7 → 91,15
/** Initilize I/O on the Serengeti machine. */
static void serengeti_init(void)
{
sgcn_init();
#ifdef CONFIG_SGCN_KBD
indev_t *kbrdin;
kbrdin = sgcnin_init();
if (kbrdin)
srlnin_init(kbrdin);
#endif
#ifdef CONFIG_SGCN_PRN
sgcnout_init();
#endif
}
 
/**
133,26 → 126,6
}
 
 
/** Kernel thread for polling keyboard.
*
* @param arg Ignored.
*/
void kkbdpoll(void *arg)
{
thread_detach(THREAD);
 
if (kbd_type != KBD_SGCN)
return;
 
while (1) {
#ifdef CONFIG_SGCN
if (kbd_type == KBD_SGCN)
sgcn_poll();
#endif
thread_usleep(KEYBOARD_POLL_PAUSE);
}
}
 
/** Acquire console back for kernel
*
*/
/branches/dynload/kernel/arch/sparc64/src/sparc64.c
37,7 → 37,6
#include <config.h>
#include <arch/trap/trap.h>
#include <arch/console.h>
#include <proc/thread.h>
#include <console/console.h>
#include <arch/boot/boot.h>
#include <arch/arch.h>
89,8 → 88,6
* But we only create 128 buckets.
*/
irq_init(1 << 11, 128);
 
standalone_sparc64_console_init();
}
}
 
104,17 → 101,7
 
void arch_post_smp_init(void)
{
static thread_t *t = NULL;
 
if (!t) {
/*
* Create thread that polls keyboard.
*/
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("Cannot create kkbdpoll.");
thread_ready(t);
}
standalone_sparc64_console_init();
}
 
/** Calibrate delay loop.
/branches/dynload/kernel/arch/sparc64/src/trap/exception.c
40,14 → 40,19
#include <arch/asm.h>
#include <arch/register.h>
#include <debug.h>
#include <print.h>
#include <symtab.h>
#include <print.h>
 
void dump_istate(istate_t *istate)
{
char *tpcs, *tnpcs;
 
tpcs = symtab_fmt_name_lookup(istate->tpc);
tnpcs = symtab_fmt_name_lookup(istate->tnpc);
 
printf("TSTATE=%#" PRIx64 "\n", istate->tstate);
printf("TPC=%#" PRIx64 " (%s)\n", istate->tpc, get_symtab_entry(istate->tpc));
printf("TNPC=%#" PRIx64 " (%s)\n", istate->tnpc, get_symtab_entry(istate->tnpc));
printf("TPC=%#" PRIx64 " (%s)\n", istate->tpc, tpcs);
printf("TNPC=%#" PRIx64 " (%s)\n", istate->tnpc, tnpcs);
}
 
/** Handle instruction_access_exception. (0x8) */
/branches/dynload/kernel/arch/sparc64/src/mm/page.c
1,5 → 1,5
/*
* Copyright (c) 2005 Jakub Jermar
* Copyright (c) 2009 Jakub Jermar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
42,126 → 42,27
#include <align.h>
#include <config.h>
 
#ifdef CONFIG_SMP
/** Entries locked in DTLB of BSP.
*
* Application processors need to have the same locked entries in their DTLBs as
* the bootstrap processor.
*/
static struct {
uintptr_t virt_page;
uintptr_t phys_page;
int pagesize_code;
} bsp_locked_dtlb_entry[DTLB_MAX_LOCKED_ENTRIES];
 
/** Number of entries in bsp_locked_dtlb_entry array. */
static count_t bsp_locked_dtlb_entries = 0;
#endif /* CONFIG_SMP */
 
/** Perform sparc64 specific initialization of paging. */
void page_arch_init(void)
{
if (config.cpu_active == 1) {
if (config.cpu_active == 1)
page_mapping_operations = &ht_mapping_operations;
} else {
 
#ifdef CONFIG_SMP
unsigned int i;
 
/*
* Copy locked DTLB entries from the BSP.
*/
for (i = 0; i < bsp_locked_dtlb_entries; i++) {
dtlb_insert_mapping(bsp_locked_dtlb_entry[i].virt_page,
bsp_locked_dtlb_entry[i].phys_page,
bsp_locked_dtlb_entry[i].pagesize_code, true,
false);
}
#endif
 
}
}
 
/** Map memory-mapped device into virtual memory.
*
* So far, only DTLB is used to map devices into memory. Chances are that there
* will be only a limited amount of devices that the kernel itself needs to
* lock in DTLB.
* We are currently using identity mapping for mapping device registers.
*
* @param physaddr Physical address of the page where the device is located.
* Must be at least page-aligned.
* @param size Size of the device's registers. Must not exceed 4M and must
* include extra space caused by the alignment.
* @param physaddr Physical address of the page where the device is
* located.
* @param size Size of the device's registers. This argument is
* ignored.
*
* @return Virtual address of the page where the device is mapped.
* @return Virtual address of the page where the device is mapped.
*/
uintptr_t hw_map(uintptr_t physaddr, size_t size)
{
unsigned int order;
unsigned int i;
 
ASSERT(config.cpu_active == 1);
 
struct {
int pagesize_code;
size_t increment;
count_t count;
} sizemap[] = {
{ PAGESIZE_8K, 0, 1 }, /* 8K */
{ PAGESIZE_8K, MMU_PAGE_SIZE, 2 }, /* 16K */
{ PAGESIZE_8K, MMU_PAGE_SIZE, 4 }, /* 32K */
{ PAGESIZE_64K, 0, 1}, /* 64K */
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 2 }, /* 128K */
{ PAGESIZE_64K, 8 * MMU_PAGE_SIZE, 4 }, /* 256K */
{ PAGESIZE_512K, 0, 1 }, /* 512K */
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 2 }, /* 1M */
{ PAGESIZE_512K, 64 * MMU_PAGE_SIZE, 4 }, /* 2M */
{ PAGESIZE_4M, 0, 1 }, /* 4M */
{ PAGESIZE_4M, 512 * MMU_PAGE_SIZE, 2 } /* 8M */
};
ASSERT(ALIGN_UP(physaddr, MMU_PAGE_SIZE) == physaddr);
ASSERT(size <= 8 * 1024 * 1024);
if (size <= MMU_FRAME_SIZE)
order = 0;
else
order = (fnzb64(size - 1) + 1) - MMU_FRAME_WIDTH;
 
/*
* Use virtual addresses that are beyond the limit of physical memory.
* Thus, the physical address space will not be wasted by holes created
* by frame_alloc().
*/
ASSERT(PA2KA(last_frame));
uintptr_t virtaddr = ALIGN_UP(PA2KA(last_frame),
1 << (order + FRAME_WIDTH));
last_frame = ALIGN_UP(KA2PA(virtaddr) + size,
1 << (order + FRAME_WIDTH));
for (i = 0; i < sizemap[order].count; i++) {
/*
* First, insert the mapping into DTLB.
*/
dtlb_insert_mapping(virtaddr + i * sizemap[order].increment,
physaddr + i * sizemap[order].increment,
sizemap[order].pagesize_code, true, false);
#ifdef CONFIG_SMP
/*
* Second, save the information about the mapping for APs.
*/
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].virt_page =
virtaddr + i * sizemap[order].increment;
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].phys_page =
physaddr + i * sizemap[order].increment;
bsp_locked_dtlb_entry[bsp_locked_dtlb_entries].pagesize_code =
sizemap[order].pagesize_code;
bsp_locked_dtlb_entries++;
#endif
}
return virtaddr;
return PA2KA(physaddr);
}
 
/** @}
/branches/dynload/kernel/arch/sparc64/src/drivers/kbd.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup sparc64
/** @addtogroup sparc64
* @{
*/
/** @file
34,12 → 34,18
 
#include <arch/drivers/kbd.h>
#include <genarch/ofw/ofw_tree.h>
 
#ifdef CONFIG_SUN_KBD
#include <genarch/kbrd/kbrd.h>
#endif
#ifdef CONFIG_Z8530
#include <genarch/kbd/z8530.h>
#include <genarch/drivers/z8530/z8530.h>
#endif
#ifdef CONFIG_NS16550
#include <genarch/kbd/ns16550.h>
#include <genarch/drivers/ns16550/ns16550.h>
#endif
 
#include <console/console.h>
#include <ddi/device.h>
#include <ddi/irq.h>
#include <arch/mm/page.h>
51,6 → 57,8
 
kbd_type_t kbd_type = KBD_UNKNOWN;
 
#ifdef CONFIG_SUN_KBD
 
/** Initialize keyboard.
*
* Traverse OpenFirmware device tree in order to find necessary
159,8 → 167,11
devno = device_assign_devno();
z8530 = (z8530_t *) hw_map(aligned_addr, offset + size) +
offset;
(void) z8530_init(z8530, devno, inr, cir, cir_arg);
indev_t *kbrdin_z8530 = z8530_init(z8530, devno, inr, cir, cir_arg);
if (kbrdin_z8530)
kbrd_init(kbrdin_z8530);
/*
* This is the necessary evil until the userspace drivers are
* entirely self-sufficient.
179,8 → 190,11
devno = device_assign_devno();
ns16550 = (ns16550_t *) hw_map(aligned_addr, offset + size) +
offset;
(void) ns16550_init(ns16550, devno, inr, cir, cir_arg);
indev_t *kbrdin_ns16550 = ns16550_init(ns16550, devno, inr, cir, cir_arg);
if (kbrdin_ns16550)
kbrd_init(kbrdin_ns16550);
/*
* This is the necessary evil until the userspace driver is
* entirely self-sufficient.
200,5 → 214,7
}
}
 
#endif
 
/** @}
*/
/branches/dynload/kernel/arch/sparc64/src/drivers/sgcn.c
34,6 → 34,7
* @brief SGCN driver.
*/
 
#include <arch.h>
#include <arch/drivers/sgcn.h>
#include <arch/drivers/kbd.h>
#include <genarch/ofw/ofw_tree.h>
41,15 → 42,14
#include <string.h>
#include <print.h>
#include <mm/page.h>
#include <ipc/irq.h>
#include <ddi/ddi.h>
#include <ddi/device.h>
#include <proc/thread.h>
#include <console/chardev.h>
#include <console/console.h>
#include <ddi/device.h>
#include <sysinfo/sysinfo.h>
#include <synch/spinlock.h>
 
#define POLL_INTERVAL 10000
 
/*
* Physical address at which the SBBC starts. This value has been obtained
* by inspecting (using Simics) memory accesses made by OBP. It is valid
73,7 → 73,7
* that the OBP console buffer is not the only console buffer
* which can be used. It is, however, used because when the kernel
* is running, the OBP buffer is not used by OBP any more but OBP
* has already made neccessary arangements so that the output will
* has already made necessary arrangements so that the output will
* be read from the OBP buffer and input will go to the OBP buffer.
* Therefore HelenOS needs to make no such arrangements any more.
*/
82,16 → 82,6
/* magic string contained at the beginning of the console buffer */
#define SGCN_BUFFER_MAGIC "CON"
 
/**
* The driver is polling based, but in order to notify the userspace
* of a key being pressed, we need to supply the interface with some
* interrupt number. The interrupt number can be arbitrary as it it
* will never be used for identifying HW interrupts, but only in
* notifying the userspace.
*/
#define FICTIONAL_INR 1
 
 
/*
* Returns a pointer to the object of a given type which is placed at the given
* offset from the SRAM beginning.
106,7 → 96,7
* offset from the console buffer beginning.
*/
#define SGCN_BUFFER(type, offset) \
((type *) (sgcn_buffer_begin + (offset)))
((type *) (sgcn_buffer_begin + (offset)))
 
/** Returns a pointer to the console buffer header. */
#define SGCN_BUFFER_HEADER (SGCN_BUFFER(sgcn_buffer_header_t, 0))
123,14 → 113,9
*/
static uintptr_t sgcn_buffer_begin;
 
/**
* SGCN IRQ structure. So far used only for notifying the userspace of the
* key being pressed, not for kernel being informed about keyboard interrupts.
*/
static irq_t sgcn_irq;
/* true iff the kernel driver should ignore pressed keys */
static bool kbd_disabled;
 
// TODO think of a way how to synchronize accesses to SGCN buffer between the kernel and the userspace
 
/*
* Ensures that writing to the buffer and consequent update of the write pointer
* are together one atomic operation.
145,21 → 130,21
 
 
/* functions referenced from definitions of I/O operations structures */
static void sgcn_noop(chardev_t *);
static void sgcn_putchar(chardev_t *, const char, bool);
static char sgcn_key_read(chardev_t *);
static void sgcn_putchar(outdev_t *, const char, bool);
 
/** character device operations */
static chardev_operations_t sgcn_ops = {
.suspend = sgcn_noop,
.resume = sgcn_noop,
.read = sgcn_key_read,
/** SGCN output device operations */
static outdev_operations_t sgcnout_ops = {
.write = sgcn_putchar
};
 
/** SGCN character device */
chardev_t sgcn_io;
/** SGCN input device operations */
static indev_operations_t sgcnin_ops = {
.poll = NULL
};
 
static indev_t sgcnin; /**< SGCN input device. */
static outdev_t sgcnout; /**< SGCN output device. */
 
/**
* Set some sysinfo values (SRAM address and SRAM size).
*/
167,7 → 152,7
{
sysinfo_set_item_val("sram.area.size", NULL, MAPPED_AREA_SIZE);
sysinfo_set_item_val("sram.address.physical", NULL,
sram_begin_physical);
sram_begin_physical);
}
 
/**
178,9 → 163,6
* property of the "/chosen" OBP node. The sram_begin variable will
* be set to the virtual address which maps to the SRAM physical
* address.
*
* It also registers the physical area of SRAM and sets some sysinfo
* values (SRAM address and SRAM size).
*/
static void init_sram_begin(void)
{
199,7 → 181,7
panic("Cannot find SRAM TOC.");
 
sram_begin_physical = SBBC_START + SBBC_SRAM_OFFSET
+ *((uint32_t *) iosram_toc->value);
+ *((uint32_t *) iosram_toc->value);
sram_begin = hw_map(sram_begin_physical, MAPPED_AREA_SIZE);
register_sram(sram_begin_physical);
218,6 → 200,11
*/
static void sgcn_buffer_begin_init(void)
{
static bool initialized;
if (initialized)
return;
 
init_sram_begin();
ASSERT(strcmp(SRAM_TOC->magic, SRAM_TOC_MAGIC) == 0);
233,17 → 220,12
sgcn_buffer_begin = sram_begin + SRAM_TOC->keys[i].offset;
sysinfo_set_item_val("sram.buffer.offset", NULL,
SRAM_TOC->keys[i].offset);
SRAM_TOC->keys[i].offset);
initialized = true;
}
 
/**
* Default suspend/resume operation for the input device.
*/
static void sgcn_noop(chardev_t *d)
{
}
 
/**
* Writes a single character to the SGCN (circular) output buffer
* and updates the output write pointer so that SGCN gets to know
* that the character has been written.
256,7 → 238,7
/* we need pointers to volatile variables */
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_wrptr_ptr = &(SGCN_BUFFER_HEADER->out_wrptr);
volatile uint32_t *out_rdptr_ptr = &(SGCN_BUFFER_HEADER->out_rdptr);
 
286,7 → 268,7
* feed character is written ('\n'), the carriage return character ('\r') is
* written straight away.
*/
static void sgcn_putchar(struct chardev * cd, const char c, bool silent)
static void sgcn_putchar(outdev_t *od, const char c, bool silent)
{
if (!silent) {
spinlock_lock(&sgcn_output_lock);
300,49 → 282,11
}
 
/**
* Called when actively reading the character. Not implemented yet.
*/
static char sgcn_key_read(chardev_t *d)
{
return (char) 0;
}
 
/**
* The driver works in polled mode, so no interrupt should be handled by it.
*/
static irq_ownership_t sgcn_claim(irq_t *irq)
{
return IRQ_DECLINE;
}
 
/**
* The driver works in polled mode, so no interrupt should be handled by it.
*/
static void sgcn_irq_handler(irq_t *irq)
{
panic("Not yet implemented, SGCN works in polled mode.");
}
 
/**
* Grabs the input for kernel.
*/
void sgcn_grab(void)
{
ipl_t ipl = interrupts_disable();
volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
/* skip all the user typed before the grab and hasn't been processed */
spinlock_lock(&sgcn_input_lock);
*in_rdptr_ptr = *in_wrptr_ptr;
spinlock_unlock(&sgcn_input_lock);
 
spinlock_lock(&sgcn_irq.lock);
sgcn_irq.notif_cfg.notify = false;
spinlock_unlock(&sgcn_irq.lock);
interrupts_restore(ipl);
kbd_disabled = true;
}
 
/**
350,12 → 294,7
*/
void sgcn_release(void)
{
ipl_t ipl = interrupts_disable();
spinlock_lock(&sgcn_irq.lock);
if (sgcn_irq.notif_cfg.answerbox)
sgcn_irq.notif_cfg.notify = true;
spinlock_unlock(&sgcn_irq.lock);
interrupts_restore(ipl);
kbd_disabled = true;
}
 
/**
363,74 → 302,82
* there are some unread characters in the input queue. If so, it picks them up
* and sends them to the upper layers of HelenOS.
*/
void sgcn_poll(void)
static void sgcn_poll()
{
uint32_t begin = SGCN_BUFFER_HEADER->in_begin;
uint32_t end = SGCN_BUFFER_HEADER->in_end;
uint32_t size = end - begin;
 
if (kbd_disabled)
return;
 
spinlock_lock(&sgcn_input_lock);
ipl_t ipl = interrupts_disable();
spinlock_lock(&sgcn_irq.lock);
/* we need pointers to volatile variables */
volatile char *buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
volatile uint32_t *in_wrptr_ptr = &(SGCN_BUFFER_HEADER->in_wrptr);
volatile uint32_t *in_rdptr_ptr = &(SGCN_BUFFER_HEADER->in_rdptr);
if (*in_rdptr_ptr != *in_wrptr_ptr) {
/* XXX: send notification to userspace */
}
spinlock_unlock(&sgcn_irq.lock);
interrupts_restore(ipl);
 
while (*in_rdptr_ptr != *in_wrptr_ptr) {
buf_ptr = (volatile char *)
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
SGCN_BUFFER(char, SGCN_BUFFER_HEADER->in_rdptr);
char c = *buf_ptr;
*in_rdptr_ptr = (((*in_rdptr_ptr) - begin + 1) % size) + begin;
if (c == '\r') {
c = '\n';
}
chardev_push_character(&sgcn_io, c);
indev_push_character(&sgcnin, c);
}
 
spinlock_unlock(&sgcn_input_lock);
}
 
/**
* A public function which initializes I/O from/to Serengeti console
* and sets it as a default input/output.
* Polling thread function.
*/
void sgcn_init(void)
static void kkbdpoll(void *arg) {
while (1) {
if (!silent) {
sgcn_poll();
}
thread_usleep(POLL_INTERVAL);
}
}
 
/**
* A public function which initializes input from the Serengeti console.
*/
indev_t *sgcnin_init(void)
{
sgcn_buffer_begin_init();
 
kbd_type = KBD_SGCN;
 
devno_t devno = device_assign_devno();
irq_initialize(&sgcn_irq);
sgcn_irq.devno = devno;
sgcn_irq.inr = FICTIONAL_INR;
sgcn_irq.claim = sgcn_claim;
sgcn_irq.handler = sgcn_irq_handler;
irq_register(&sgcn_irq);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.type", NULL, KBD_SGCN);
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, FICTIONAL_INR);
sysinfo_set_item_val("fb.kind", NULL, 4);
 
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("Cannot create kkbdpoll.");
thread_ready(t);
chardev_initialize("sgcn_io", &sgcn_io, &sgcn_ops);
stdin = &sgcn_io;
stdout = &sgcn_io;
indev_initialize("sgcnin", &sgcnin, &sgcnin_ops);
 
return &sgcnin;
}
 
/**
* A public function which initializes output to the Serengeti console.
*/
void sgcnout_init(void)
{
sgcn_buffer_begin_init();
 
sysinfo_set_item_val("fb.kind", NULL, 4);
 
outdev_initialize("sgcnout", &sgcnout, &sgcnout_ops);
stdout = &sgcnout;
}
 
/** @}
*/
/branches/dynload/kernel/arch/ia64/include/ski/ski.h
35,22 → 35,17
#ifndef KERN_ia64_SKI_H_
#define KERN_ia64_SKI_H_
 
#include <arch/types.h>
#include <console/console.h>
#include <console/chardev.h>
 
#define SKI_INIT_CONSOLE 20
#define SKI_GETCHAR 21
#define SKI_PUTCHAR 31
 
extern chardev_t ski_uconsole;
 
extern void ski_init_console(void);
 
extern indev_t *skiin_init(void);
extern void skiout_init(void);
extern void ski_kbd_grab(void);
extern void ski_kbd_release(void);
 
extern void kkbdpoll(void *arg);
 
#endif
 
/** @}
/branches/dynload/kernel/arch/ia64/src/smp/smp.c
52,8 → 52,6
#include <ddi/irq.h>
#include <ddi/device.h>
#include <arch/bootinfo.h>
#include <genarch/kbd/i8042.h>
#include <genarch/kbd/ns16550.h>
#include <smp/smp.h>
#include <smp/ipi.h>
#include <arch/atomic.h>
/branches/dynload/kernel/arch/ia64/src/asm.S
51,7 → 51,7
 
adds r14 = 7, in1
mov r2 = ar.lc
mov r8 = in0
mov r8 = in0 ;;
and r14 = -8, r14 ;;
cmp.ne p6, p7 = r14, in1
(p7) br.cond.dpnt 3f ;;
/branches/dynload/kernel/arch/ia64/src/ia64.c
54,8 → 54,11
#include <arch/bootinfo.h>
#include <genarch/drivers/legacy/ia32/io.h>
#include <genarch/drivers/ega/ega.h>
#include <genarch/kbd/i8042.h>
#include <genarch/kbd/ns16550.h>
#include <genarch/kbrd/kbrd.h>
#include <genarch/srln/srln.h>
#include <genarch/drivers/i8042/i8042.h>
#include <genarch/drivers/ns16550/ns16550.h>
#include <arch/drivers/kbd.h>
#include <smp/smp.h>
#include <smp/ipi.h>
#include <arch/atomic.h>
65,7 → 68,7
#include <string.h>
 
/* NS16550 as a COM 1 */
#define NS16550_IRQ (4 + LEGACY_INTERRUPT_BASE)
#define NS16550_IRQ (4 + LEGACY_INTERRUPT_BASE)
 
bootinfo_t *bootinfo;
 
127,20 → 130,13
 
}
 
 
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
iosapic_init();
irq_init(INR_COUNT, INR_COUNT);
#ifdef SKI
ski_init_console();
#else
ega_init(EGA_BASE, EGA_VIDEORAM);
#endif
}
it_init();
it_init();
}
 
void arch_post_cpu_init(void)
153,31 → 149,44
 
void arch_post_smp_init(void)
{
/*
* Create thread that polls keyboard.
*/
#ifdef SKI
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (!t)
panic("Cannot create kkbdpoll.");
thread_ready(t);
#endif
 
#ifdef I460GX
devno_t devno = device_assign_devno();
inr_t inr;
 
indev_t *in;
in = skiin_init();
if (in)
srln_init(in);
skiout_init();
#endif
#ifdef CONFIG_EGA
ega_init(EGA_BASE, EGA_VIDEORAM);
#endif
#ifdef CONFIG_NS16550
inr = NS16550_IRQ;
(void) ns16550_init((ns16550_t *)NS16550_BASE, devno, inr, NULL, NULL);
devno_t devno_ns16550 = device_assign_devno();
indev_t *kbrdin_ns16550
= ns16550_init((ns16550_t *) NS16550_BASE, devno_ns16550, NS16550_IRQ, NULL, NULL);
if (kbrdin_ns16550)
srln_init(kbrdin_ns16550);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.devno", NULL, devno_ns16550);
sysinfo_set_item_val("kbd.inr", NULL, NS16550_IRQ);
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550);
sysinfo_set_item_val("kbd.address.physical", NULL,
(uintptr_t) NS16550_BASE);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) NS16550_BASE);
#else
inr = IRQ_KBD;
(void) i8042_init((i8042_t *)I8042_BASE, devno, inr);
#endif
#ifdef CONFIG_I8042
devno_t devno_i8042 = device_assign_devno();
indev_t *kbrdin_i8042 = i8042_init((i8042_t *) I8042_BASE, devno_i8042, IRQ_KBD);
if (kbrdin_i8042)
kbrd_init(kbrdin_i8042);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.devno", NULL, devno_i8042);
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD);
sysinfo_set_item_val("kbd.type", NULL, KBD_LEGACY);
sysinfo_set_item_val("kbd.address.physical", NULL,
(uintptr_t) I8042_BASE);
184,11 → 193,7
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) I8042_BASE);
#endif
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, inr);
#endif
 
sysinfo_set_item_val("ia64_iospace", NULL, true);
sysinfo_set_item_val("ia64_iospace.address", NULL, true);
sysinfo_set_item_val("ia64_iospace.address.virtual", NULL, IO_OFFSET);
/branches/dynload/kernel/arch/ia64/src/ski/ski.c
35,25 → 35,17
#include <arch/ski/ski.h>
#include <console/console.h>
#include <console/chardev.h>
#include <arch/interrupt.h>
#include <sysinfo/sysinfo.h>
#include <arch/types.h>
#include <ddi/device.h>
#include <ddi/irq.h>
#include <ipc/irq.h>
#include <proc/thread.h>
#include <synch/spinlock.h>
#include <arch/asm.h>
#include <arch/drivers/kbd.h>
#include <arch.h>
 
#define SKI_KBD_INR 0
static indev_t skiin; /**< Ski input device. */
static outdev_t skiout; /**< Ski output device. */
 
static irq_t ski_kbd_irq;
static devno_t ski_kbd_devno;
 
chardev_t ski_console;
chardev_t ski_uconsole;
 
static bool kbd_disabled;
 
/** Display character on debug console
64,7 → 56,7
* @param d Character device.
* @param ch Character to be printed.
*/
static void ski_putchar(chardev_t *d, const char ch, bool silent)
static void ski_putchar(outdev_t *d, const char ch, bool silent)
{
if (!silent) {
asm volatile (
81,6 → 73,14
}
}
 
static indev_operations_t skiin_ops = {
.poll = NULL
};
 
static outdev_operations_t skiout_ops = {
.write = ski_putchar
};
 
/** Ask debug console if a key was pressed.
*
* Use SSC (Simulator System Call) to
107,104 → 107,47
return (int32_t) ch;
}
 
/**
* This is a blocking wrapper for ski_getchar().
* To be used when the kernel crashes.
*/
static char ski_getchar_blocking(chardev_t *d)
{
int ch;
while(!(ch = ski_getchar()));
if (ch == '\r')
ch = '\n';
return (char) ch;
}
 
/** Ask keyboard if a key was pressed. */
static void poll_keyboard(void)
{
char ch;
static char last;
ipl_t ipl;
ipl = interrupts_disable();
if (kbd_disabled) {
interrupts_restore(ipl);
if (kbd_disabled)
return;
}
spinlock_lock(&ski_kbd_irq.lock);
ch = ski_getchar();
if(ch == '\r')
ch = '\n';
if (ch) {
if (ski_kbd_irq.notif_cfg.notify &&
ski_kbd_irq.notif_cfg.answerbox) {
chardev_push_character(&ski_uconsole, ch);
/* XXX: send notification to userspace */
} else {
chardev_push_character(&ski_console, ch);
}
last = ch;
spinlock_unlock(&ski_kbd_irq.lock);
interrupts_restore(ipl);
indev_push_character(&skiin, ch);
return;
}
 
if (last) {
if (ski_kbd_irq.notif_cfg.notify &&
ski_kbd_irq.notif_cfg.answerbox) {
chardev_push_character(&ski_uconsole, 0);
/* XXX: send notification to userspace */
}
last = 0;
}
 
spinlock_unlock(&ski_kbd_irq.lock);
interrupts_restore(ipl);
}
 
/* Called from getc(). */
static void ski_kbd_enable(chardev_t *d)
{
kbd_disabled = false;
}
#define POLL_INTERVAL 10000 /* 10 ms */
 
/* Called from getc(). */
static void ski_kbd_disable(chardev_t *d)
/** Kernel thread for polling keyboard. */
static void kkbdpoll(void *arg)
{
kbd_disabled = true;
while (1) {
if (!silent) {
poll_keyboard();
}
thread_usleep(POLL_INTERVAL);
}
}
 
/** Decline to service hardware IRQ.
*
* This is only a virtual IRQ, so always decline.
*
* @return Always IRQ_DECLINE.
*/
static irq_ownership_t ski_kbd_claim(irq_t *irq)
{
return IRQ_DECLINE;
}
 
static chardev_operations_t ski_ops = {
.resume = ski_kbd_enable,
.suspend = ski_kbd_disable,
.write = ski_putchar,
.read = ski_getchar_blocking
};
 
/** Initialize debug console
*
* Issue SSC (Simulator System Call) to
* to open debug console.
*/
void ski_init_console(void)
static void ski_init(void)
{
static bool initialized;
 
if (initialized)
return;
asm volatile (
"mov r15 = %0\n"
"break 0x80000\n"
212,58 → 155,47
: "i" (SKI_INIT_CONSOLE)
: "r15", "r8"
);
initialized = true;
}
 
chardev_initialize("ski_console", &ski_console, &ski_ops);
chardev_initialize("ski_uconsole", &ski_uconsole, &ski_ops);
stdin = &ski_console;
stdout = &ski_console;
indev_t *skiin_init(void)
{
ski_init();
 
ski_kbd_devno = device_assign_devno();
irq_initialize(&ski_kbd_irq);
ski_kbd_irq.inr = SKI_KBD_INR;
ski_kbd_irq.devno = ski_kbd_devno;
ski_kbd_irq.claim = ski_kbd_claim;
irq_register(&ski_kbd_irq);
indev_initialize("skiin", &skiin, &skiin_ops);
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true);
if (t)
thread_ready(t);
else
return NULL;
 
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.inr", NULL, SKI_KBD_INR);
sysinfo_set_item_val("kbd.devno", NULL, ski_kbd_devno);
sysinfo_set_item_val("kbd.type", NULL, KBD_SKI);
 
return &skiin;
}
 
 
void skiout_init(void)
{
ski_init();
 
outdev_initialize("skiout", &skiout, &skiout_ops);
stdout = &skiout;
 
sysinfo_set_item_val("fb", NULL, false);
}
 
void ski_kbd_grab(void)
{
ipl_t ipl = interrupts_disable();
spinlock_lock(&ski_kbd_irq.lock);
ski_kbd_irq.notif_cfg.notify = false;
spinlock_unlock(&ski_kbd_irq.lock);
interrupts_restore(ipl);
kbd_disabled = true;
}
 
void ski_kbd_release(void)
{
ipl_t ipl = interrupts_disable();
spinlock_lock(&ski_kbd_irq.lock);
if (ski_kbd_irq.notif_cfg.answerbox)
ski_kbd_irq.notif_cfg.notify = true;
spinlock_unlock(&ski_kbd_irq.lock);
interrupts_restore(ipl);
kbd_disabled = false;
}
 
 
#define POLL_INTERVAL 50000 /* 50 ms */
 
/** Kernel thread for polling keyboard. */
void kkbdpoll(void *arg)
{
while (1) {
poll_keyboard();
thread_usleep(POLL_INTERVAL);
}
}
 
/** @}
*/
/branches/dynload/kernel/arch/ia64/src/interrupt.c
38,7 → 38,6
#include <ddi/irq.h>
#include <panic.h>
#include <print.h>
#include <symtab.h>
#include <debug.h>
#include <console/console.h>
#include <arch/types.h>
54,6 → 53,7
#include <ipc/ipc.h>
#include <synch/spinlock.h>
#include <mm/tlb.h>
#include <symtab.h>
 
#define VECTORS_64_BUNDLE 20
#define VECTORS_16_BUNDLE 48
137,9 → 137,9
{
char *ifa, *iipa, *iip;
 
ifa = get_symtab_entry(istate->cr_ifa);
iipa = get_symtab_entry(istate->cr_iipa);
iip = get_symtab_entry(istate->cr_iip);
ifa = symtab_fmt_name_lookup(istate->cr_ifa);
iipa = symtab_fmt_name_lookup(istate->cr_iipa);
iip = symtab_fmt_name_lookup(istate->cr_iip);
 
putchar('\n');
printf("Interrupted context dump:\n");
/branches/dynload/kernel/arch/arm32/include/machine.h
File deleted
/branches/dynload/kernel/arch/arm32/include/debug/print.h
File deleted
/branches/dynload/kernel/arch/arm32/include/asm/boot.h
37,7 → 37,7
#define KERN_arm32_ASM_BOOT_H_
 
/** Size of a temporary stack used for initial kernel start. */
#define TEMP_STACK_SIZE 0x100
#define TEMP_STACK_SIZE 0x100
 
#endif
 
/branches/dynload/kernel/arch/arm32/include/console.h
36,13 → 36,6
#ifndef KERN_arm32_CONSOLE_H_
#define KERN_arm32_CONSOLE_H_
 
 
/** Initializes console.
*
* @param devno Console device number.
*/
extern void console_init(devno_t devno);
 
#endif
 
/** @}
/branches/dynload/kernel/arch/arm32/include/drivers/gxemul.h
38,41 → 38,33
#ifndef KERN_arm32_GXEMUL_H_
#define KERN_arm32_GXEMUL_H_
 
#include <console/chardev.h>
 
/** Last interrupt number (beginning from 0) whose status is probed
/** Last interrupt number (beginning from 0) whose status is probed
* from interrupt controller
*/
#define GXEMUL_IRQC_MAX_IRQ 8
#define GXEMUL_IRQC_MAX_IRQ 8
#define GXEMUL_KBD_IRQ 2
#define GXEMUL_TIMER_IRQ 4
 
/** Timer frequency */
#define GXEMUL_TIMER_FREQ 100
#define GXEMUL_TIMER_FREQ 100
 
/** Struct containing mappings of gxemul HW devices into kernel part
* of virtual address space.
*/
typedef struct {
uintptr_t videoram;
uintptr_t kbd;
uintptr_t rtc;
uintptr_t rtc_freq;
uintptr_t rtc_ack;
uintptr_t irqc;
uintptr_t irqc_mask;
uintptr_t irqc_unmask;
} gxemul_hw_map_t;
#define GXEMUL_KBD_ADDRESS 0x10000000
#define GXEMUL_MP_ADDRESS 0x11000000
#define GXEMUL_FB_ADDRESS 0x12000000
#define GXEMUL_RTC_ADDRESS 0x15000000
#define GXEMUL_IRQC_ADDRESS 0x16000000
 
extern void gxemul_hw_map_init(void);
extern void gxemul_console_init(devno_t devno);
extern void gxemul_release_console(void);
extern void gxemul_grab_console(void);
extern void gxemul_timer_irq_start(void);
extern void gxemul_debug_putc(char ch);
extern void gxemul_cpu_halt(void);
extern void gxemul_irq_exception(int exc_no, istate_t *istate);
extern size_t gxemul_get_memory_size(void);
extern uintptr_t gxemul_get_fb_address(void);
extern void *gxemul_kbd;
extern void *gxemul_rtc;
extern void *gxemul_irqc;
 
#define GXEMUL_HALT_OFFSET 0x010
#define GXEMUL_RTC_FREQ_OFFSET 0x100
#define GXEMUL_MP_MEMSIZE_OFFSET 0x090
#define GXEMUL_RTC_ACK_OFFSET 0x110
 
extern void gxemul_init(void);
 
#endif
 
/** @}
/branches/dynload/kernel/arch/arm32/Makefile.inc
51,7 → 51,6
arch/$(KARCH)/src/cpu/cpu.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/interrupt.c \
arch/$(KARCH)/src/debug/print.c \
arch/$(KARCH)/src/console.c \
arch/$(KARCH)/src/exception.c \
arch/$(KARCH)/src/userspace.c \
/branches/dynload/kernel/arch/arm32/src/debug/print.c
File deleted
/branches/dynload/kernel/arch/arm32/src/exception.c
34,13 → 34,12
*/
 
#include <arch/exception.h>
#include <arch/debug/print.h>
#include <arch/memstr.h>
#include <arch/regutils.h>
#include <interrupt.h>
#include <arch/machine.h>
#include <arch/mm/page_fault.h>
#include <arch/barrier.h>
#include <arch/drivers/gxemul.h>
#include <print.h>
#include <syscall/syscall.h>
 
260,7 → 259,10
/** Low-level Prefetch Abort Exception handler. */
static void prefetch_abort_exception_entry(void)
{
asm("sub lr, lr, #4");
asm volatile (
"sub lr, lr, #4"
);
PROCESS_EXCEPTION(EXC_PREFETCH_ABORT);
}
 
267,7 → 269,10
/** Low-level Data Abort Exception handler. */
static void data_abort_exception_entry(void)
{
asm("sub lr, lr, #8");
asm volatile (
"sub lr, lr, #8"
);
PROCESS_EXCEPTION(EXC_DATA_ABORT);
}
 
279,7 → 284,10
*/
static void irq_exception_entry(void)
{
asm("sub lr, lr, #4");
asm volatile (
"sub lr, lr, #4"
);
setup_stack_and_save_regs();
switch_to_irq_servicing_mode();
299,6 → 307,12
istate->r3, istate->r4, istate->r5, istate->r6);
}
 
/** Returns the mask of active interrupts. */
static inline uint32_t gxemul_irqc_get_sources(void)
{
return *((uint32_t *) gxemul_irqc);
}
 
/** Interrupt Exception handler.
*
* Determines the sources of interrupt and calls their handlers.
305,7 → 319,23
*/
static void irq_exception(int exc_no, istate_t *istate)
{
machine_irq_exception(exc_no, istate);
uint32_t sources = gxemul_irqc_get_sources();
unsigned int i;
for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
printf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
/** Fills exception vectors with appropriate exception handlers. */
329,7 → 359,7
install_handler((unsigned) irq_exception_entry,
(unsigned *) EXC_IRQ_VEC);
install_handler((unsigned)fiq_exception_entry,
install_handler((unsigned) fiq_exception_entry,
(unsigned *) EXC_FIQ_VEC);
}
 
379,18 → 409,18
*/
void print_istate(istate_t *istate)
{
dprintf("istate dump:\n");
 
dprintf(" r0: %x r1: %x r2: %x r3: %x\n",
printf("istate dump:\n");
printf(" r0: %x r1: %x r2: %x r3: %x\n",
istate->r0, istate->r1, istate->r2, istate->r3);
dprintf(" r4: %x r5: %x r6: %x r7: %x\n",
printf(" r4: %x r5: %x r6: %x r7: %x\n",
istate->r4, istate->r5, istate->r6, istate->r7);
dprintf(" r8: %x r8: %x r10: %x r11: %x\n",
printf(" r8: %x r8: %x r10: %x r11: %x\n",
istate->r8, istate->r9, istate->r10, istate->r11);
dprintf(" r12: %x sp: %x lr: %x spsr: %x\n",
printf(" r12: %x sp: %x lr: %x spsr: %x\n",
istate->r12, istate->sp, istate->lr, istate->spsr);
 
dprintf(" pc: %x\n", istate->pc);
printf(" pc: %x\n", istate->pc);
}
 
/** @}
/branches/dynload/kernel/arch/arm32/src/console.c
26,24 → 26,17
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup arm32
/** @addtogroup arm32
* @{
*/
/** @file
/** @file
* @brief Console.
*/
 
#include <console/console.h>
#include <arch/console.h>
#include <arch/machine.h>
 
#include <genarch/fb/fb.h>
 
void console_init(devno_t devno)
{
machine_console_init(devno);
}
 
/** Acquire console back for kernel. */
void arch_grab_console(void)
{
/branches/dynload/kernel/arch/arm32/src/arm32.c
39,13 → 39,16
#include <ddi/device.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <genarch/drivers/dsrln/dsrlnin.h>
#include <genarch/drivers/dsrln/dsrlnout.h>
#include <genarch/srln/srln.h>
#include <sysinfo/sysinfo.h>
#include <ddi/irq.h>
#include <arch/debug/print.h>
#include <arch/drivers/gxemul.h>
#include <print.h>
#include <config.h>
#include <interrupt.h>
#include <arch/regutils.h>
#include <arch/machine.h>
#include <userspace.h>
#include <macros.h>
#include <string.h>
75,18 → 78,15
/** Performs arm32 specific initialization afterr mm is initialized. */
void arch_post_mm_init(void)
{
machine_hw_map_init();
 
gxemul_init();
/* Initialize exception dispatch table */
exception_init();
 
interrupt_init();
console_init(device_assign_devno());
 
#ifdef CONFIG_FB
fb_properties_t prop = {
.addr = machine_get_fb_address(),
.addr = GXEMUL_FB_ADDRESS,
.offset = 0,
.x = 640,
.y = 480,
94,7 → 94,11
.visual = VISUAL_BGR_8_8_8,
};
fb_init(&prop);
#endif
#else
#ifdef CONFIG_ARM_PRN
dsrlnout_init((ioport8_t *) gxemul_kbd);
#endif /* CONFIG_ARM_PRN */
#endif /* CONFIG_FB */
}
 
/** Performs arm32 specific tasks needed after cpu is initialized.
123,6 → 127,26
*/
void arch_post_smp_init(void)
{
#ifdef CONFIG_ARM_KBD
devno_t devno = device_assign_devno();
/*
* Initialize the msim/GXemul keyboard port. Then initialize the serial line
* module and connect it to the msim/GXemul keyboard. Enable keyboard interrupts.
*/
indev_t *kbrdin = dsrlnin_init((dsrlnin_t *) gxemul_kbd, devno, GXEMUL_KBD_IRQ);
if (kbrdin)
srln_init(kbrdin);
/*
* This is the necessary evil until the userspace driver is entirely
* self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, (unative_t) gxemul_kbd);
#endif
}
 
 
156,7 → 180,8
/** Halts CPU. */
void cpu_halt(void)
{
machine_cpu_halt();
*((char *) (gxemul_kbd + GXEMUL_HALT_OFFSET))
= 0;
}
 
/** Reboot. */
/branches/dynload/kernel/arch/arm32/src/mm/page_fault.c
34,7 → 34,6
*/
#include <panic.h>
#include <arch/exception.h>
#include <arch/debug/print.h>
#include <arch/mm/page_fault.h>
#include <mm/as.h>
#include <genarch/mm/page_pt.h>
182,10 → 181,10
 
if (ret == AS_PF_FAULT) {
print_istate(istate);
dprintf("page fault - pc: %x, va: %x, status: %x(%x), "
printf("page fault - pc: %x, va: %x, status: %x(%x), "
"access:%d\n", istate->pc, badvaddr, fsr.status, fsr,
access);
 
fault_if_from_uspace(istate, "Page fault: %#x.", badvaddr);
panic("Page fault.");
}
201,7 → 200,7
int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate);
 
if (ret == AS_PF_FAULT) {
dprintf("prefetch_abort\n");
printf("prefetch_abort\n");
print_istate(istate);
panic("page fault - prefetch_abort at address: %x.",
istate->pc);
/branches/dynload/kernel/arch/arm32/src/mm/frame.c
35,9 → 35,8
 
#include <mm/frame.h>
#include <arch/mm/frame.h>
#include <arch/machine.h>
#include <arch/drivers/gxemul.h>
#include <config.h>
#include <arch/debug/print.h>
 
/** Address of the last frame in the memory. */
uintptr_t last_frame = 0;
45,10 → 44,11
/** Creates memory zones. */
void frame_arch_init(void)
{
/* all memory as one zone */
zone_create(0, ADDR2PFN(machine_get_memory_size()),
last_frame = *((uintptr_t *) (GXEMUL_MP_ADDRESS + GXEMUL_MP_MEMSIZE_OFFSET));
/* All memory as one zone */
zone_create(0, ADDR2PFN(last_frame),
BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0);
last_frame = machine_get_memory_size();
/* blacklist boot page table */
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME,
58,10 → 58,9
/** Frees the boot page table. */
void boot_page_table_free(void)
{
int i;
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++) {
unsigned int i;
for (i = 0; i < BOOT_PAGE_TABLE_SIZE_IN_FRAMES; i++)
frame_free(i * FRAME_SIZE + BOOT_PAGE_TABLE_ADDRESS);
}
}
 
/** @}
/branches/dynload/kernel/arch/arm32/src/mm/page.c
51,19 → 51,15
*/
void page_arch_init(void)
{
int flags = PAGE_CACHEABLE;
page_mapping_operations = &pt_mapping_operations;
uintptr_t cur;
int flags;
 
page_mapping_operations = &pt_mapping_operations;
 
flags = PAGE_CACHEABLE;
 
/* PA2KA(identity) mapping for all frames until last_frame */
for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
/* Kernel identity mapping */
for (cur = 0; cur < last_frame; cur += FRAME_SIZE)
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
}
/* create mapping for exception table at high offset */
/* Create mapping for exception table at high offset */
#ifdef HIGH_EXCEPTION_VECTORS
void *virtaddr = frame_alloc(ONE_FRAME, FRAME_KA);
page_mapping_insert(AS_KERNEL, EXC_BASE_ADDRESS, KA2PA(virtaddr), flags);
70,9 → 66,9
#else
#error "Only high exception vector supported now"
#endif
 
as_switch(NULL, AS_KERNEL);
 
boot_page_table_free();
}
 
93,7 → 89,7
panic("Unable to map physical memory %p (%d bytes).",
physaddr, size)
}
 
uintptr_t virtaddr = PA2KA(last_frame);
pfn_t i;
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) {
101,7 → 97,7
physaddr + PFN2ADDR(i),
PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
}
 
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
return virtaddr;
}
/branches/dynload/kernel/arch/arm32/src/panic.S
31,5 → 31,5
.global panic_printf
 
panic_printf:
bl debug_printf
bl printf
bl cpu_halt
/branches/dynload/kernel/arch/arm32/src/interrupt.c
35,13 → 35,16
 
#include <arch/asm.h>
#include <arch/regutils.h>
#include <arch/drivers/gxemul.h>
#include <ddi/irq.h>
#include <arch/machine.h>
#include <ddi/device.h>
#include <interrupt.h>
 
/** Initial size of a table holding interrupt handlers. */
#define IRQ_COUNT 8
 
static irq_t gxemul_timer_irq;
 
/** Disable interrupts.
*
* @return Old interrupt priority level.
49,7 → 52,7
ipl_t interrupts_disable(void)
{
ipl_t ipl = current_status_reg_read();
 
current_status_reg_control_write(STATUS_REG_IRQ_DISABLED_BIT | ipl);
return ipl;
62,9 → 65,9
ipl_t interrupts_enable(void)
{
ipl_t ipl = current_status_reg_read();
 
current_status_reg_control_write(ipl & ~STATUS_REG_IRQ_DISABLED_BIT);
 
return ipl;
}
 
88,6 → 91,41
return current_status_reg_read();
}
 
/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void gxemul_timer_start(uint32_t frequency)
{
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_FREQ_OFFSET))
= frequency;
}
 
static irq_ownership_t gxemul_timer_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void gxemul_timer_irq_handler(irq_t *irq)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
/* acknowledge tick */
*((uint32_t *) (gxemul_rtc + GXEMUL_RTC_ACK_OFFSET))
= 0;
}
 
/** Initialize basic tables for exception dispatching
* and starts the timer.
*/
94,7 → 132,16
void interrupt_init(void)
{
irq_init(IRQ_COUNT, IRQ_COUNT);
machine_timer_irq_start();
irq_initialize(&gxemul_timer_irq);
gxemul_timer_irq.devno = device_assign_devno();
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
gxemul_timer_irq.claim = gxemul_timer_claim;
gxemul_timer_irq.handler = gxemul_timer_irq_handler;
irq_register(&gxemul_timer_irq);
gxemul_timer_start(GXEMUL_TIMER_FREQ);
}
 
/** @}
/branches/dynload/kernel/arch/arm32/src/drivers/gxemul.c
33,333 → 33,19
* @brief GXemul drivers.
*/
 
#include <interrupt.h>
#include <console/chardev.h>
#include <arch/drivers/gxemul.h>
#include <console/console.h>
#include <sysinfo/sysinfo.h>
#include <print.h>
#include <ddi/device.h>
#include <mm/page.h>
#include <arch/machine.h>
#include <arch/debug/print.h>
 
/* Addresses of devices. */
#define GXEMUL_VIDEORAM 0x10000000
#define GXEMUL_KBD 0x10000000
#define GXEMUL_HALT_OFFSET 0x10
#define GXEMUL_RTC 0x15000000
#define GXEMUL_RTC_FREQ_OFFSET 0x100
#define GXEMUL_RTC_ACK_OFFSET 0x110
#define GXEMUL_IRQC 0x16000000
#define GXEMUL_IRQC_MASK_OFFSET 0x4
#define GXEMUL_IRQC_UNMASK_OFFSET 0x8
#define GXEMUL_MP 0x11000000
#define GXEMUL_MP_MEMSIZE_OFFSET 0x0090
#define GXEMUL_FB 0x12000000
void *gxemul_kbd;
void *gxemul_rtc;
void *gxemul_irqc;
 
/* IRQs */
#define GXEMUL_KBD_IRQ 2
#define GXEMUL_TIMER_IRQ 4
 
static gxemul_hw_map_t gxemul_hw_map;
static chardev_t console;
static irq_t gxemul_console_irq;
static irq_t gxemul_timer_irq;
 
static bool hw_map_init_called = false;
 
static void gxemul_kbd_enable(chardev_t *dev);
static void gxemul_kbd_disable(chardev_t *dev);
static void gxemul_write(chardev_t *dev, const char ch, bool silent);
static char gxemul_do_read(chardev_t *dev);
 
static chardev_operations_t gxemul_ops = {
.resume = gxemul_kbd_enable,
.suspend = gxemul_kbd_disable,
.write = gxemul_write,
.read = gxemul_do_read,
};
 
 
/** Returns the mask of active interrupts. */
static inline uint32_t gxemul_irqc_get_sources(void)
void gxemul_init(void)
{
return *((uint32_t *) gxemul_hw_map.irqc);
gxemul_kbd = (void *) hw_map(GXEMUL_KBD_ADDRESS, PAGE_SIZE);
gxemul_rtc = (void *) hw_map(GXEMUL_RTC_ADDRESS, PAGE_SIZE);
gxemul_irqc = (void *) hw_map(GXEMUL_IRQC_ADDRESS, PAGE_SIZE);
}
 
 
/** Masks interrupt.
*
* @param irq interrupt number
*/
static inline void gxemul_irqc_mask(uint32_t irq)
{
*((uint32_t *) gxemul_hw_map.irqc_mask) = irq;
}
 
 
/** Unmasks interrupt.
*
* @param irq interrupt number
*/
static inline void gxemul_irqc_unmask(uint32_t irq)
{
*((uint32_t *) gxemul_hw_map.irqc_unmask) = irq;
}
 
 
/** Initializes #gxemul_hw_map. */
void gxemul_hw_map_init(void)
{
gxemul_hw_map.videoram = hw_map(GXEMUL_VIDEORAM, PAGE_SIZE);
gxemul_hw_map.kbd = hw_map(GXEMUL_KBD, PAGE_SIZE);
gxemul_hw_map.rtc = hw_map(GXEMUL_RTC, PAGE_SIZE);
gxemul_hw_map.irqc = hw_map(GXEMUL_IRQC, PAGE_SIZE);
 
gxemul_hw_map.rtc_freq = gxemul_hw_map.rtc + GXEMUL_RTC_FREQ_OFFSET;
gxemul_hw_map.rtc_ack = gxemul_hw_map.rtc + GXEMUL_RTC_ACK_OFFSET;
gxemul_hw_map.irqc_mask = gxemul_hw_map.irqc + GXEMUL_IRQC_MASK_OFFSET;
gxemul_hw_map.irqc_unmask = gxemul_hw_map.irqc +
GXEMUL_IRQC_UNMASK_OFFSET;
 
hw_map_init_called = true;
}
 
 
/** Putchar that works with gxemul.
*
* @param dev Not used.
* @param ch Characted to be printed.
*/
static void gxemul_write(chardev_t *dev, const char ch, bool silent)
{
if (!silent)
*((char *) gxemul_hw_map.videoram) = ch;
}
 
/** Enables gxemul keyboard (interrupt unmasked).
*
* @param dev Not used.
*
* Called from getc().
*/
static void gxemul_kbd_enable(chardev_t *dev)
{
gxemul_irqc_unmask(GXEMUL_KBD_IRQ);
}
 
/** Disables gxemul keyboard (interrupt masked).
*
* @param dev not used
*
* Called from getc().
*/
static void gxemul_kbd_disable(chardev_t *dev)
{
gxemul_irqc_mask(GXEMUL_KBD_IRQ);
}
 
/** Read character using polling, assume interrupts disabled.
*
* @param dev Not used.
*/
static char gxemul_do_read(chardev_t *dev)
{
char ch;
 
while (1) {
ch = *((volatile char *) gxemul_hw_map.kbd);
if (ch) {
if (ch == '\r')
return '\n';
if (ch == 0x7f)
return '\b';
return ch;
}
}
}
 
/** Process keyboard interrupt.
*
* @param irq IRQ information.
*/
static void gxemul_irq_handler(irq_t *irq)
{
char ch = 0;
ch = *((char *) gxemul_hw_map.kbd);
if (ch == '\r') {
ch = '\n';
}
if (ch == 0x7f) {
ch = '\b';
}
chardev_push_character(&console, ch);
}
 
static irq_ownership_t gxemul_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Initializes console object representing gxemul console.
*
* @param devno device number.
*/
void gxemul_console_init(devno_t devno)
{
chardev_initialize("gxemul_console", &console, &gxemul_ops);
stdin = &console;
stdout = &console;
irq_initialize(&gxemul_console_irq);
gxemul_console_irq.devno = devno;
gxemul_console_irq.inr = GXEMUL_KBD_IRQ;
gxemul_console_irq.claim = gxemul_claim;
gxemul_console_irq.handler = gxemul_irq_handler;
irq_register(&gxemul_console_irq);
gxemul_irqc_unmask(GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, GXEMUL_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, gxemul_hw_map.kbd);
}
 
/** Starts gxemul Real Time Clock device, which asserts regular interrupts.
*
* @param frequency Interrupts frequency (0 disables RTC).
*/
static void gxemul_timer_start(uint32_t frequency)
{
*((uint32_t*) gxemul_hw_map.rtc_freq) = frequency;
}
 
static irq_ownership_t gxemul_timer_claim(irq_t *irq)
{
return IRQ_ACCEPT;
}
 
/** Timer interrupt handler.
*
* @param irq Interrupt information.
* @param arg Not used.
*/
static void gxemul_timer_irq_handler(irq_t *irq)
{
/*
* We are holding a lock which prevents preemption.
* Release the lock, call clock() and reacquire the lock again.
*/
spinlock_unlock(&irq->lock);
clock();
spinlock_lock(&irq->lock);
 
/* acknowledge tick */
*((uint32_t*) gxemul_hw_map.rtc_ack) = 0;
}
 
/** Initializes and registers timer interrupt handler. */
static void gxemul_timer_irq_init(void)
{
irq_initialize(&gxemul_timer_irq);
gxemul_timer_irq.devno = device_assign_devno();
gxemul_timer_irq.inr = GXEMUL_TIMER_IRQ;
gxemul_timer_irq.claim = gxemul_timer_claim;
gxemul_timer_irq.handler = gxemul_timer_irq_handler;
 
irq_register(&gxemul_timer_irq);
}
 
 
/** Starts timer.
*
* Initiates regular timer interrupts after initializing
* corresponding interrupt handler.
*/
void gxemul_timer_irq_start(void)
{
gxemul_timer_irq_init();
gxemul_timer_start(GXEMUL_TIMER_FREQ);
}
 
/** Returns the size of emulated memory.
*
* @return Size in bytes.
*/
size_t gxemul_get_memory_size(void)
{
return *((int *) (GXEMUL_MP + GXEMUL_MP_MEMSIZE_OFFSET));
}
 
/** Prints a character.
*
* @param ch Character to be printed.
*/
void gxemul_debug_putc(char ch)
{
char *addr = 0;
if (!hw_map_init_called) {
addr = (char *) GXEMUL_KBD;
} else {
addr = (char *) gxemul_hw_map.videoram;
}
 
*(addr) = ch;
}
 
/** Stops gxemul. */
void gxemul_cpu_halt(void)
{
char * addr = 0;
if (!hw_map_init_called) {
addr = (char *) GXEMUL_KBD;
} else {
addr = (char *) gxemul_hw_map.videoram;
}
*(addr + GXEMUL_HALT_OFFSET) = '\0';
}
 
/** Gxemul specific interrupt exception handler.
*
* Determines sources of the interrupt from interrupt controller and
* calls high-level handlers for them.
*
* @param exc_no Interrupt exception number.
* @param istate Saved processor state.
*/
void gxemul_irq_exception(int exc_no, istate_t *istate)
{
uint32_t sources = gxemul_irqc_get_sources();
int i;
for (i = 0; i < GXEMUL_IRQC_MAX_IRQ; i++) {
if (sources & (1 << i)) {
irq_t *irq = irq_dispatch_and_lock(i);
if (irq) {
/* The IRQ handler was found. */
irq->handler(irq);
spinlock_unlock(&irq->lock);
} else {
/* Spurious interrupt.*/
dprintf("cpu%d: spurious interrupt (inum=%d)\n",
CPU->id, i);
}
}
}
}
 
/** Returns address of framebuffer device.
*
* @return Address of framebuffer device.
*/
uintptr_t gxemul_get_fb_address(void)
{
return (uintptr_t) GXEMUL_FB;
}
 
/** @}
*/
/branches/dynload/kernel/arch/ppc32/src/ppc32.c
79,6 → 79,8
void arch_post_mm_init(void)
{
if (config.cpu_active == 1) {
 
#ifdef CONFIG_FB
/* Initialize framebuffer */
if (bootinfo.screen.addr) {
unsigned int visual;
109,6 → 111,7
};
fb_init(&prop);
}
#endif
/* Initialize IRQ routing */
irq_init(IRQ_COUNT, IRQ_COUNT);
159,7 → 162,9
*/
void arch_grab_console(void)
{
#ifdef CONFIG_FB
fb_redraw();
#endif
}
 
/** Return console to userspace
/branches/dynload/kernel/arch/ppc32/src/mm/tlb.c
39,10 → 39,9
#include <mm/as.h>
#include <arch.h>
#include <print.h>
#include <macros.h>
#include <symtab.h>
#include <macros.h>
 
 
static unsigned int seed = 10;
static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;
 
118,15 → 117,11
 
static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate)
{
char *symbol = "";
char *sym2 = "";
char *symbol;
char *sym2;
 
char *str = get_symtab_entry(istate->pc);
if (str)
symbol = str;
str = get_symtab_entry(istate->lr);
if (str)
sym2 = str;
symbol = symtab_fmt_name_lookup(istate->pc);
sym2 = symtab_fmt_name_lookup(istate->lr);
 
fault_if_from_uspace(istate,
"PHT Refill Exception on %p.", badvaddr);
/branches/dynload/kernel/arch/ppc32/src/drivers/cuda.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ppc32
/** @addtogroup ppc32
* @{
*/
/** @file
204,32 → 204,9
}
 
 
/* Called from getc(). */
static void cuda_resume(chardev_t *d)
{
}
 
 
/* Called from getc(). */
static void cuda_suspend(chardev_t *d)
{
}
 
 
static char key_read(chardev_t *d)
{
char ch;
ch = 0;
return ch;
}
 
 
static chardev_t kbrd;
static chardev_operations_t ops = {
.suspend = cuda_suspend,
.resume = cuda_resume,
.read = key_read
static indev_t kbrd;
static indev_operations_t ops = {
.poll = NULL
};
 
 
251,11 → 228,11
static void cuda_irq_handler(irq_t *irq)
{
int scan_code = cuda_get_scancode();
if (scan_code != -1) {
uint8_t scancode = (uint8_t) scan_code;
if ((scancode & 0x80) != 0x80)
chardev_push_character(&kbrd, lchars[scancode & 0x7f]);
indev_push_character(&kbrd, lchars[scancode & 0x7f]);
}
}
 
268,7 → 245,7
{
cuda = (uint8_t *) hw_map(base, size);
chardev_initialize("cuda_kbd", &kbrd, &ops);
indev_initialize("cuda_kbd", &kbrd, &ops);
stdin = &kbrd;
irq_initialize(&cuda_irq);
/branches/dynload/kernel/arch/amd64/include/pm.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64
/** @addtogroup amd64
* @{
*/
/** @file
36,63 → 36,60
#define KERN_amd64_PM_H_
 
#ifndef __ASM__
# include <arch/types.h>
# include <arch/context.h>
#include <arch/types.h>
#include <arch/context.h>
#endif
 
#define IDT_ITEMS 64
#define GDT_ITEMS 8
#define IDT_ITEMS 64
#define GDT_ITEMS 8
 
 
#define NULL_DES 0
/* Warning: Do not reorder next items, unless you look into syscall.c!!! */
#define KTEXT_DES 1
#define KDATA_DES 2
#define UDATA_DES 3
#define UTEXT_DES 4
#define KTEXT32_DES 5
/* EndOfWarning */
#define TSS_DES 6
#define NULL_DES 0
/* Warning: Do not reorder the following items, unless you look into syscall.c! */
#define KTEXT_DES 1
#define KDATA_DES 2
#define UDATA_DES 3
#define UTEXT_DES 4
#define KTEXT32_DES 5
/* End of warning */
#define TSS_DES 6
 
 
 
#ifdef CONFIG_FB
 
#define VESA_INIT_DES 8
#define VESA_INIT_SEGMENT 0x8000
#undef GDT_ITEMS
#define GDT_ITEMS 9
#define VESA_INIT_DES 8
#define VESA_INIT_SEGMENT 0x8000
 
#endif /*CONFIG_FB*/
#undef GDT_ITEMS
#define GDT_ITEMS 9
 
#endif /* CONFIG_FB */
 
#define gdtselector(des) ((des) << 3)
#define idtselector(des) ((des) << 4)
 
#define gdtselector(des) ((des) << 3)
#define idtselector(des) ((des) << 4)
#define PL_KERNEL 0
#define PL_USER 3
 
#define PL_KERNEL 0
#define PL_USER 3
#define AR_PRESENT ( 1 << 7)
#define AR_DATA (2 << 3)
#define AR_CODE (3 << 3)
#define AR_WRITABLE (1 << 1)
#define AR_READABLE (1 << 1)
#define AR_TSS (0x09)
#define AR_INTERRUPT (0x0e)
#define AR_TRAP (0x0f)
 
#define AR_PRESENT (1<<7)
#define AR_DATA (2<<3)
#define AR_CODE (3<<3)
#define AR_WRITABLE (1<<1)
#define AR_READABLE (1<<1)
#define AR_TSS (0x9)
#define AR_INTERRUPT (0xe)
#define AR_TRAP (0xf)
#define DPL_KERNEL (PL_KERNEL << 5)
#define DPL_USER (PL_USER << 5)
 
#define DPL_KERNEL (PL_KERNEL<<5)
#define DPL_USER (PL_USER<<5)
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */
 
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16*1024+1) /* 16K for bitmap + 1 terminating byte for convenience */
#define IO_PORTS (64 * 1024)
 
#define IO_PORTS (64*1024)
 
#ifndef __ASM__
 
struct descriptor {
typedef struct {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
103,10 → 100,9
unsigned special: 1;
unsigned granularity : 1;
unsigned base_24_31: 8;
} __attribute__ ((packed));
typedef struct descriptor descriptor_t;
} __attribute__ ((packed)) descriptor_t;
 
struct tss_descriptor {
typedef struct {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
121,10 → 117,9
unsigned base_24_31: 8;
unsigned base_32_63 : 32;
unsigned : 32;
} __attribute__ ((packed));
typedef struct tss_descriptor tss_descriptor_t;
} __attribute__ ((packed)) tss_descriptor_t;
 
struct idescriptor {
typedef struct {
unsigned offset_0_15: 16;
unsigned selector: 16;
unsigned ist:3;
135,22 → 130,19
unsigned offset_16_31: 16;
unsigned offset_32_63: 32;
unsigned : 32;
} __attribute__ ((packed));
typedef struct idescriptor idescriptor_t;
} __attribute__ ((packed)) idescriptor_t;
 
struct ptr_16_64 {
typedef struct {
uint16_t limit;
uint64_t base;
} __attribute__ ((packed));
typedef struct ptr_16_64 ptr_16_64_t;
} __attribute__ ((packed)) ptr_16_64_t;
 
struct ptr_16_32 {
typedef struct {
uint16_t limit;
uint32_t base;
} __attribute__ ((packed));
typedef struct ptr_16_32 ptr_16_32_t;
} __attribute__ ((packed)) ptr_16_32_t;
 
struct tss {
typedef struct {
uint32_t reserve1;
uint64_t rsp0;
uint64_t rsp1;
167,8 → 159,7
uint16_t reserve4;
uint16_t iomap_base;
uint8_t iomap[TSS_IOMAP_SIZE];
} __attribute__ ((packed));
typedef struct tss tss_t;
} __attribute__ ((packed)) tss_t;
 
extern tss_t *tss_p;
 
/branches/dynload/kernel/arch/amd64/include/asm.h
69,7 → 69,11
 
static inline void cpu_halt(void)
{
asm volatile ("hlt\n");
asm volatile (
"0:\n"
" hlt\n"
" jmp 0b\n"
);
}
 
 
338,7 → 342,7
* @param gdtr_reg Address of memory from where to load GDTR.
*
*/
static inline void gdtr_load(struct ptr_16_64 *gdtr_reg)
static inline void gdtr_load(ptr_16_64_t *gdtr_reg)
{
asm volatile (
"lgdtq %[gdtr_reg]\n"
351,7 → 355,7
* @param gdtr_reg Address of memory to where to load GDTR.
*
*/
static inline void gdtr_store(struct ptr_16_64 *gdtr_reg)
static inline void gdtr_store(ptr_16_64_t *gdtr_reg)
{
asm volatile (
"sgdtq %[gdtr_reg]\n"
364,7 → 368,7
* @param idtr_reg Address of memory from where to load IDTR.
*
*/
static inline void idtr_load(struct ptr_16_64 *idtr_reg)
static inline void idtr_load(ptr_16_64_t *idtr_reg)
{
asm volatile (
"lidtq %[idtr_reg]\n"
/branches/dynload/kernel/arch/amd64/include/cpu.h
35,9 → 35,9
#ifndef KERN_amd64_CPU_H_
#define KERN_amd64_CPU_H_
 
#define RFLAGS_IF (1 << 9)
#define RFLAGS_DF (1 << 10)
#define RFLAGS_RF (1 << 16)
#define RFLAGS_IF (1 << 9)
#define RFLAGS_DF (1 << 10)
#define RFLAGS_RF (1 << 16)
 
#define EFER_MSR_NUM 0xc0000080
#define AMD_SCE_FLAG 0
62,17 → 62,15
int family;
int model;
int stepping;
struct tss *tss;
tss_t *tss;
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
} cpu_arch_t;
 
struct star_msr {
};
 
struct lstar_msr {
};
 
extern void set_efer_flag(int flag);
/branches/dynload/kernel/arch/amd64/Makefile.inc
46,7 → 46,7
## Accepted CPUs
#
 
ifeq ($(MACHINE),opteron)
ifeq ($(PROCESSOR),opteron)
CMN2 := -march=opteron
GCC_CFLAGS += $(CMN2)
ICC_CFLAGS += $(CMN2)
/branches/dynload/kernel/arch/amd64/src/amd64.c
43,7 → 43,8
#include <genarch/drivers/legacy/ia32/io.h>
#include <genarch/drivers/ega/ega.h>
#include <arch/drivers/vesa.h>
#include <genarch/kbd/i8042.h>
#include <genarch/drivers/i8042/i8042.h>
#include <genarch/kbrd/kbrd.h>
#include <arch/drivers/i8254.h>
#include <arch/drivers/i8259.h>
#include <arch/boot/boot.h>
149,13 → 150,17
/* hard clock */
i8254_init();
#ifdef CONFIG_FB
if (vesa_present())
vesa_init();
else
#endif
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */
#ifdef CONFIG_EGA
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */
#else
{}
#endif
/* Enable debugger */
debugger_init();
188,11 → 193,20
 
void arch_post_smp_init(void)
{
#ifdef CONFIG_PC_KBD
devno_t devno = device_assign_devno();
/* keyboard controller */
(void) i8042_init((i8042_t *) I8042_BASE, devno, IRQ_KBD);
 
/*
* Initialize the i8042 controller. Then initialize the keyboard
* module and connect it to i8042. Enable keyboard interrupts.
*/
indev_t *kbrdin = i8042_init((i8042_t *) I8042_BASE, devno, IRQ_KBD);
if (kbrdin) {
kbrd_init(kbrdin);
trap_virtual_enable_irqs(1 << IRQ_KBD);
}
/*
* This is the necessary evil until the userspace driver is entirely
* self-sufficient.
*/
203,6 → 217,7
(uintptr_t) I8042_BASE);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) I8042_BASE);
#endif
}
 
void calibrate_delay_loop(void)
238,9 → 253,14
void arch_grab_console(void)
{
#ifdef CONFIG_FB
vesa_redraw();
if (vesa_present())
vesa_redraw();
else
#endif
#ifdef CONFIG_EGA
ega_redraw();
#else
ega_redraw();
{}
#endif
}
 
/branches/dynload/kernel/arch/amd64/src/pm.c
137,8 → 137,8
 
void gdt_tss_setlimit(descriptor_t *d, uint32_t limit)
{
struct tss_descriptor *td = (tss_descriptor_t *) d;
 
tss_descriptor_t *td = (tss_descriptor_t *) d;
td->limit_0_15 = limit & 0xffff;
td->limit_16_19 = (limit >> 16) & 0xf;
}
185,14 → 185,14
*/
void pm_init(void)
{
descriptor_t *gdt_p = (struct descriptor *) gdtr.base;
descriptor_t *gdt_p = (descriptor_t *) gdtr.base;
tss_descriptor_t *tss_desc;
 
/*
* Each CPU has its private GDT and TSS.
* All CPUs share one IDT.
*/
 
if (config.cpu_active == 1) {
idt_init();
/*
200,20 → 200,19
* the heap hasn't been initialized so far.
*/
tss_p = &tss;
}
else {
} else {
/* We are going to use malloc, which may return
* non boot-mapped pointer, initialize the CR3 register
* ahead of page_init */
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table);
 
tss_p = (struct tss *) malloc(sizeof(tss_t), FRAME_ATOMIC);
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC);
if (!tss_p)
panic("Cannot allocate TSS.");
}
 
tss_initialize(tss_p);
 
tss_desc = (tss_descriptor_t *) (&gdt_p[TSS_DES]);
tss_desc->present = 1;
tss_desc->type = AR_TSS;
221,7 → 220,7
gdt_tss_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p);
gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1);
 
gdtr_load(&gdtr);
idtr_load(&idtr);
/*
/branches/dynload/kernel/arch/amd64/src/ddi/ddi.c
57,15 → 57,15
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
{
count_t bits;
 
bits = ioaddr + size;
if (bits > IO_PORTS)
return ENOENT;
 
if (task->arch.iomap.bits < bits) {
bitmap_t oldiomap;
uint8_t *newmap;
/*
* The I/O permission bitmap is too small and needs to be grown.
*/
77,17 → 77,17
bitmap_initialize(&oldiomap, task->arch.iomap.map,
task->arch.iomap.bits);
bitmap_initialize(&task->arch.iomap, newmap, bits);
 
/*
* Mark the new range inaccessible.
*/
bitmap_set_range(&task->arch.iomap, oldiomap.bits,
bits - oldiomap.bits);
 
/*
* In case there really existed smaller iomap,
* copy its contents and deallocate it.
*/
*/
if (oldiomap.bits) {
bitmap_copy(&task->arch.iomap, &oldiomap,
oldiomap.bits);
94,17 → 94,17
free(oldiomap.map);
}
}
 
/*
* Enable the range and we are done.
*/
bitmap_clear_range(&task->arch.iomap, (index_t) ioaddr, (count_t) size);
 
/*
* Increment I/O Permission bitmap generation counter.
*/
task->arch.iomapver++;
 
return 0;
}
 
122,7 → 122,7
descriptor_t *gdt_p;
tss_descriptor_t *tss_desc;
count_t ver;
 
/* First, copy the I/O Permission Bitmap. */
spinlock_lock(&TASK->lock);
ver = TASK->arch.iomapver;
140,7 → 140,7
bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8);
}
spinlock_unlock(&TASK->lock);
 
/*
* Second, adjust TSS segment limit.
* Take the extra ending byte will all bits set into account.
151,10 → 151,10
gdtr_load(&cpugdtr);
/*
* Before we load new TSS limit, the current TSS descriptor
* type must be changed to describe inactive TSS.
*/
tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];
* Before we load new TSS limit, the current TSS descriptor
* type must be changed to describe inactive TSS.
*/
tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];
tss_desc->type = AR_TSS;
tr_load(gdtselector(TSS_DES));
/branches/dynload/kernel/arch/amd64/src/boot/vesa_ret.inc
0,0 → 1,19
.code32
vesa_init_protected:
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds # kernel data + stack
movw %cx, %ss
#
# Simics seems to remove hidden part of GS on entering user mode
# when _visible_ part of GS does not point to user-mode segment.
#
movw $gdtselector(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
movl $START_STACK, %esp # initialize stack pointer
jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
/branches/dynload/kernel/arch/amd64/src/boot/boot.S
37,7 → 37,7
#include <arch/cpuid.h>
 
#define START_STACK (BOOT_OFFSET - BOOT_STACK_SIZE)
 
.section K_TEXT_START, "ax"
 
.code32
46,7 → 46,7
multiboot_header:
.long MULTIBOOT_HEADER_MAGIC
.long MULTIBOOT_HEADER_FLAGS
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
.long multiboot_header
.long unmapped_ktext_start
.long 0
55,15 → 55,19
 
multiboot_image_start:
cld
movl $START_STACK, %esp # initialize stack pointer
lgdtl bootstrap_gdtr # initialize Global Descriptor Table register
 
movl $START_STACK, %esp # initialize stack pointer
lgdtl bootstrap_gdtr # initialize Global Descriptor Table register
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds # kernel data + stack
movw %cx, %ds # kernel data + stack
movw %cx, %ss
#
# Simics seems to remove hidden part of GS on entering user mode
# when _visible_ part of GS does not point to user-mode segment
# when _visible_ part of GS does not point to user-mode segment.
#
movw $gdtselector(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
71,17 → 75,19
jmpl $gdtselector(KTEXT32_DES), $multiboot_meeting_point
multiboot_meeting_point:
movl %eax, grub_eax # save parameters from GRUB
movl %eax, grub_eax # save parameters from GRUB
movl %ebx, grub_ebx
#
# Protected 32-bit. We want to reuse the code-seg descriptor,
# the Default operand size must not be 1 when entering long mode
# the Default operand size must not be 1 when entering long mode.
#
movl $(INTEL_CPUID_EXTENDED), %eax
cpuid
cmp $(INTEL_CPUID_EXTENDED), %eax
movl $(INTEL_CPUID_EXTENDED), %eax
cpuid
cmp $(INTEL_CPUID_EXTENDED), %eax
ja extended_cpuid_supported
movl $extended_cpuid_msg, %esi
jmp error_halt
90,11 → 96,11
movl $(AMD_CPUID_EXTENDED), %eax
cpuid
bt $(AMD_EXT_LONG_MODE), %edx
jc long_mode_supported
jc long_mode_supported
movl $long_mode_msg, %esi
jmp error_halt
 
long_mode_supported:
bt $(AMD_EXT_NOEXECUTE), %edx
108,7 → 114,7
movl $(INTEL_CPUID_STANDARD), %eax
cpuid
bt $(INTEL_FXSAVE), %edx
jc fx_supported
jc fx_supported
movl $fx_msg, %esi
jmp error_halt
116,59 → 122,43
fx_supported:
bt $(INTEL_SSE2), %edx
jc sse2_supported
jc sse2_supported
movl $sse2_msg, %esi
jmp error_halt
sse2_supported:
#ifdef CONFIG_FB
mov $vesa_init, %esi
mov $VESA_INIT_SEGMENT << 4, %edi
mov $e_vesa_init - vesa_init, %ecx
rep movsb
 
mov $VESA_INIT_SEGMENT << 4, %edi
jmpl *%edi
vesa_meeting_point:
mov %esi, KA2PA(vesa_ph_addr)
mov %di, KA2PA(vesa_height)
shr $16, %edi
mov %di, KA2PA(vesa_width)
mov %bx, KA2PA(vesa_scanline)
shr $16, %ebx
mov %bx, KA2PA(vesa_bpp)
#endif
#include "vesa_prot.inc"
 
#
# Enable 64-bit page translation entries - CR4.PAE = 1.
# Paging is not enabled until after long mode is enabled
# Paging is not enabled until after long mode is enabled.
#
movl %cr4, %eax
btsl $5, %eax
movl %eax, %cr4
 
# Set up paging tables
# set up paging tables
leal ptl_0, %eax
movl %eax, %cr3
# Enable long mode
# enable long mode
movl $EFER_MSR_NUM, %ecx # EFER MSR number
rdmsr # Read EFER
btsl $AMD_LME_FLAG, %eax # Set LME = 1
wrmsr # Write EFER
movl $EFER_MSR_NUM, %ecx # EFER MSR number
rdmsr # read EFER
btsl $AMD_LME_FLAG, %eax # set LME = 1
wrmsr # write EFER
# Enable paging to activate long mode (set CR0.PG = 1)
# enable paging to activate long mode (set CR0.PG = 1)
movl %cr0, %eax
btsl $31, %eax
movl %eax, %cr0
# At this point we are in compatibility mode
# at this point we are in compatibility mode
jmpl $gdtselector(KTEXT_DES), $start64
 
175,262 → 165,29
.code64
start64:
movq $(PA2KA(START_STACK)), %rsp
 
# arch_pre_main(grub_eax, grub_ebx)
# call arch_pre_main(grub_eax, grub_ebx)
xorq %rdi, %rdi
movl grub_eax, %edi
xorq %rsi, %rsi
movl grub_ebx, %esi
call arch_pre_main
 
call main_bsp
 
# Not reached.
cli
hlt
 
#ifdef CONFIG_FB
.code32
vesa_init:
jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init
call main_bsp
.code16
vesa_init_real:
# not reached
mov %cr0, %eax
and $~1, %eax
mov %eax, %cr0
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
vesa_init_real2:
mov $VESA_INIT_SEGMENT, %bx
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
mov %bx, %ds
mov %bx, %ss
movl $0x0000fffc, %esp
movl $0x0000fffc, %ebp
#define VESA_INFO_SIZE 1024
cli
hlt0:
hlt
jmp hlt0
 
#define VESA_MODE_ATTRIBUTES_OFFSET 0
#define VESA_MODE_LIST_PTR_OFFSET 14
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_WIDTH_OFFSET 18
#define VESA_MODE_HEIGHT_OFFSET 20
#define VESA_MODE_BPP_OFFSET 25
#define VESA_MODE_PHADDR_OFFSET 40
 
#define VESA_END_OF_MODES 0xffff
 
#define VESA_OK 0x4f
 
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
#define VESA_SET_PALETTE 0x4f09
 
#define CONFIG_VESA_BPP_a 255
 
#if CONFIG_VESA_BPP == 24
#define CONFIG_VESA_BPP_VARIANT 32
#endif
 
mov $VESA_GET_INFO, %ax
mov $e_vesa_init - vesa_init, %di
push %di
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
mov %si, %gs
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
add $VESA_INFO_SIZE, %di
 
1:# Try next mode
mov %gs:(%si), %cx
cmp $VESA_END_OF_MODES, %cx
jz 0f
inc %si
inc %si
push %cx
push %di
push %si
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %si
pop %di
pop %cx
cmp $VESA_OK, %al
jnz 0f
mov $CONFIG_VESA_WIDTH, %ax
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_HEIGHT, %ax
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_BPP, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
 
#ifdef CONFIG_VESA_BPP_VARIANT
jz 2f
mov $CONFIG_VESA_BPP_VARIANT, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
#endif
jnz 1b
2:
mov %cx, %bx
or $0xc000, %bx
push %di
mov $VESA_SET_MODE, %ax
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
 
#if CONFIG_VESA_BPP == 8
# Set 3:2:3 VGA palette
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
push %di
mov $vga323 - vesa_init, %di
mov $0x100, %ecx
bt $5, %ax # Test if VGA compatible registers are present
jnc vga_compat
# Try VESA routine to set palette
mov $VESA_SET_PALETTE, %ax
xor %bl, %bl
xor %dx, %dx
int $0x10
cmp $0x00, %ah
je vga_not_compat
vga_compat:
# Try VGA registers to set palette
movw $0x3c6, %dx # Set palette mask
movb $0xff, %al
outb %al, %dx
movw $0x3c8, %dx # First index to set
xor %al, %al
outb %al, %dx
movw $0x3c9, %dx # Data port
vga_loop:
movb %es:2(%di), %al
outb %al, %dx
movb %es:1(%di), %al
outb %al, %dx
movb %es:(%di), %al
outb %al, %dx
addw $4, %di
loop vga_loop
vga_not_compat:
pop %di
#endif
mov VESA_MODE_PHADDR_OFFSET(%di), %esi
mov VESA_MODE_WIDTH_OFFSET(%di), %ax
shl $16, %eax
mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
mov VESA_MODE_BPP_OFFSET(%di), %bl
xor %bh, %bh
shl $16, %ebx
mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
mov %eax, %edi
8:
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
jmp 9f
9:
ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4)
0:# No prefered mode found
mov $0x111, %cx
push %di
push %cx
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %cx
pop %di
cmp $VESA_OK, %al
jnz 1f
jz 2b # Force relative jump
 
1:
mov $0x0003, %ax
int $0x10
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA
xor %ax, %ax
jz 8b # Force relative jump
 
vga323:
#include "vga323.pal"
.code32
vesa_init_protect:
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %ds # kernel data + stack
movw %cx, %ss
# Simics seems to remove hidden part of GS on entering user mode
# when _visible_ part of GS does not point to user-mode segment
movw $gdtselector(UDATA_DES), %cx
movw %cx, %fs
movw %cx, %gs
movl $START_STACK, %esp # initialize stack pointer
jmpl $gdtselector(KTEXT32_DES), $vesa_meeting_point
.align 4
e_vesa_init:
#endif
 
# Print string from %esi to EGA display (in red) and halt
error_halt:
movl $0xb8000, %edi # base of EGA text mode memory
movl $0xb8000, %edi # base of EGA text mode memory
xorl %eax, %eax
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
438,7 → 195,7
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
447,7 → 204,9
cmp $1920, %ax
jbe cursor_ok
movw $1920, %ax # sanity check for the cursor on the last line
movw $1920, %ax # sanity check for the cursor on the last line
cursor_ok:
movw %ax, %bx
454,7 → 213,7
shl $1, %eax
addl %eax, %edi
movw $0x0c00, %ax # black background, light red foreground
movw $0x0c00, %ax # black background, light red foreground
ploop:
lodsb
461,11 → 220,11
cmp $0, %al
je ploop_end
stosw
inc %bx
inc %bx
jmp ploop
ploop_end:
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
473,7 → 232,7
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
480,17 → 239,20
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
cli
hlt
hlt1:
hlt
jmp hlt1
 
#include "vesa_real.inc"
 
.section K_INI_PTLS, "aw", @progbits
 
#
# Macro for generating initial page table contents.
# @param cnt Number of entries to generat. Must be multiple of 8.
# @param g Number of GB that will be added to the mapping.
# @param cnt Number of entries to generat. Must be multiple of 8.
# @param g Number of GB that will be added to the mapping.
#
.macro ptl2gen cnt g
.if \cnt
542,7 → 304,7
# Mapping of [0; 1G) at -2G
.quad ptl_2_0g + (PTL_WRITABLE | PTL_PRESENT)
.fill 1, 8, 0
 
.align 4096
.global ptl_0
ptl_0:
/branches/dynload/kernel/arch/amd64/src/boot/vesa_real.inc
0,0 → 1,0
link ../../../ia32/src/boot/vesa_real.inc
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/dynload/kernel/arch/amd64/src/boot/vesa_prot.inc
0,0 → 1,0
link ../../../ia32/src/boot/vesa_prot.inc
Property changes:
Added: svn:special
+*
\ No newline at end of property
/branches/dynload/kernel/arch/amd64/src/boot/memmap.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup amd64mm
/** @addtogroup amd64mm
* @{
*/
/** @file
/branches/dynload/kernel/arch/amd64/src/debugger.c
35,7 → 35,6
#include <arch/debugger.h>
#include <console/kconsole.h>
#include <console/cmd.h>
#include <symtab.h>
#include <print.h>
#include <panic.h>
#include <interrupt.h>
44,6 → 43,7
#include <debug.h>
#include <func.h>
#include <smp/ipi.h>
#include <symtab.h>
 
typedef struct {
uintptr_t address; /**< Breakpoint address */
229,12 → 229,13
*((unative_t *) breakpoints[slot].address));
}
}
printf("Reached breakpoint %d:%lx(%s)\n", slot, getip(istate),
get_symtab_entry(getip(istate)));
 
printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate),
symtab_fmt_name_lookup(getip(istate)));
 
#ifdef CONFIG_KCONSOLE
atomic_set(&haltstate, 1);
kconsole("debug", "Debug console ready (type 'exit' to continue)\n", false);
kconsole("debug", "Debug console ready.\n", false);
atomic_set(&haltstate, 0);
#endif
}
355,7 → 356,8
for (i = 0; i < BKPOINTS_MAX; i++)
if (breakpoints[i].address) {
symbol = get_symtab_entry(breakpoints[i].address);
symbol = symtab_fmt_name_lookup(
breakpoints[i].address);
 
#ifdef __32_BITS__
printf("%-2u %-5d %#10zx %s\n", i,
/branches/dynload/kernel/arch/amd64/src/interrupt.c
43,7 → 43,6
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch.h>
#include <symtab.h>
#include <arch/asm.h>
#include <proc/scheduler.h>
#include <proc/thread.h>
52,6 → 51,7
#include <arch/ddi/ddi.h>
#include <interrupt.h>
#include <ddi/irq.h>
#include <symtab.h>
 
/*
* Interrupt and exception dispatching.
64,10 → 64,8
void decode_istate(int n, istate_t *istate)
{
char *symbol;
/* uint64_t *x = &istate->stack[0]; */
 
if (!(symbol = get_symtab_entry(istate->rip)))
symbol = "";
symbol = symtab_fmt_name_lookup(istate->rip);
 
printf("-----EXCEPTION(%d) OCCURED----- ( %s )\n", n, __func__);
printf("%%rip: %#llx (%s)\n", istate->rip, symbol);
/branches/dynload/kernel/arch/mips32/include/console.h
35,8 → 35,6
#ifndef KERN_mips32_CONSOLE_H_
#define KERN_mips32_CONSOLE_H_
 
extern void console_init(devno_t devno);
 
#endif
 
/** @}
/branches/dynload/kernel/arch/mips32/include/mm/tlb.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32mm
/** @addtogroup mips32mm
* @{
*/
/** @file
40,42 → 40,38
#include <arch/mm/asid.h>
#include <arch/exception.h>
 
#ifdef TLBCNT
# define TLB_ENTRY_COUNT TLBCNT
#else
# define TLB_ENTRY_COUNT 48
#endif
#define TLB_ENTRY_COUNT 48
 
#define TLB_WIRED 1
#define TLB_KSTACK_WIRED_INDEX 0
#define TLB_WIRED 1
#define TLB_KSTACK_WIRED_INDEX 0
 
#define TLB_PAGE_MASK_4K (0x000 << 13)
#define TLB_PAGE_MASK_16K (0x003 << 13)
#define TLB_PAGE_MASK_64K (0x00f << 13)
#define TLB_PAGE_MASK_256K (0x03f << 13)
#define TLB_PAGE_MASK_1M (0x0ff << 13)
#define TLB_PAGE_MASK_4M (0x3ff << 13)
#define TLB_PAGE_MASK_16M (0xfff << 13)
#define TLB_PAGE_MASK_4K (0x000 << 13)
#define TLB_PAGE_MASK_16K (0x003 << 13)
#define TLB_PAGE_MASK_64K (0x00f << 13)
#define TLB_PAGE_MASK_256K (0x03f << 13)
#define TLB_PAGE_MASK_1M (0x0ff << 13)
#define TLB_PAGE_MASK_4M (0x3ff << 13)
#define TLB_PAGE_MASK_16M (0xfff << 13)
 
#define PAGE_UNCACHED 2
#define PAGE_CACHEABLE_EXC_WRITE 5
#define PAGE_UNCACHED 2
#define PAGE_CACHEABLE_EXC_WRITE 5
 
typedef union {
struct {
#ifdef BIG_ENDIAN
unsigned : 2; /* zero */
unsigned pfn : 24; /* frame number */
unsigned c : 3; /* cache coherency attribute */
unsigned d : 1; /* dirty/write-protect bit */
unsigned v : 1; /* valid bit */
unsigned g : 1; /* global bit */
unsigned : 2; /* zero */
unsigned pfn : 24; /* frame number */
unsigned c : 3; /* cache coherency attribute */
unsigned d : 1; /* dirty/write-protect bit */
unsigned v : 1; /* valid bit */
unsigned g : 1; /* global bit */
#else
unsigned g : 1; /* global bit */
unsigned v : 1; /* valid bit */
unsigned d : 1; /* dirty/write-protect bit */
unsigned c : 3; /* cache coherency attribute */
unsigned pfn : 24; /* frame number */
unsigned : 2; /* zero */
unsigned g : 1; /* global bit */
unsigned v : 1; /* valid bit */
unsigned d : 1; /* dirty/write-protect bit */
unsigned c : 3; /* cache coherency attribute */
unsigned pfn : 24; /* frame number */
unsigned : 2; /* zero */
#endif
} __attribute__ ((packed));
uint32_t value;
163,7 → 159,7
asm volatile ("tlbwr\n\t");
}
 
#define tlb_invalidate(asid) tlb_invalidate_asid(asid)
#define tlb_invalidate(asid) tlb_invalidate_asid(asid)
 
extern void tlb_invalid(istate_t *istate);
extern void tlb_refill(istate_t *istate);
/branches/dynload/kernel/arch/mips32/include/drivers/serial.h
File deleted
/branches/dynload/kernel/arch/mips32/include/drivers/msim.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
/** @addtogroup mips32
* @{
*/
/** @file
36,16 → 36,10
#define KERN_mips32_MSIM_H_
 
/** Address of devices. */
#define MSIM_VIDEORAM 0x90000000
#define MSIM_KBD_ADDRESS 0x90000000
#define MSIM_KBD_IRQ 2
#define MSIM_VIDEORAM 0x90000000
#define MSIM_KBD_ADDRESS 0x90000000
#define MSIM_KBD_IRQ 2
 
#include <console/chardev.h>
 
void msim_console(devno_t devno);
void msim_kbd_release(void);
void msim_kbd_grab(void);
 
#endif
 
/** @}
/branches/dynload/kernel/arch/mips32/Makefile.inc
30,10 → 30,11
#
 
BFD_ARCH = mips
BFD = binary
TARGET = mipsel-linux-gnu
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel
 
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mips3
 
DEFS += -D__32_BITS__
 
42,29 → 43,16
 
ifeq ($(MACHINE),lgxemul)
BFD_NAME = elf32-tradlittlemips
BFD = binary
GCC_CFLAGS += -mips3
endif
ifeq ($(MACHINE),bgxemul)
BFD_NAME = elf32-bigmips
BFD = ecoff-bigmips
BFD_NAME = elf32-tradbigmips
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips
TARGET = mips-sgi-irix5
GCC_CFLAGS += -EB -DBIG_ENDIAN -mips3
TARGET = mips-linux-gnu
GCC_CFLAGS += -DBIG_ENDIAN
endif
ifeq ($(MACHINE),simics)
# SIMICS 4kc emulation is broken, although for instructions
# that do not bother us
BFD_NAME = elf32-tradlittlemips
BFD = elf32-tradlittlemips
GCC_CFLAGS += -mhard-float -mips3 -DTLBCNT=16
TLBCNT = 16
endif
ifeq ($(MACHINE),msim)
BFD_NAME = elf32-tradlittlemips
BFD = binary
GCC_CFLAGS += -mhard-float -mips3
GCC_CFLAGS += -mhard-float
endif
 
ARCH_SOURCES = \
85,7 → 73,5
arch/$(KARCH)/src/mm/as.c \
arch/$(KARCH)/src/fpu_context.c \
arch/$(KARCH)/src/ddi/ddi.c \
arch/$(KARCH)/src/drivers/msim.c \
arch/$(KARCH)/src/drivers/serial.c \
arch/$(KARCH)/src/smp/dorder.c \
arch/$(KARCH)/src/smp/smp.c
/branches/dynload/kernel/arch/mips32/src/drivers/msim.c
File deleted
/branches/dynload/kernel/arch/mips32/src/drivers/serial.c
File deleted
/branches/dynload/kernel/arch/mips32/src/exception.c
41,12 → 41,12
#include <arch.h>
#include <debug.h>
#include <proc/thread.h>
#include <symtab.h>
#include <print.h>
#include <interrupt.h>
#include <func.h>
#include <ddi/irq.h>
#include <arch/debugger.h>
#include <symtab.h>
 
static char * exctable[] = {
"Interrupt",
73,17 → 73,13
 
static void print_regdump(istate_t *istate)
{
char *pcsymbol = "";
char *rasymbol = "";
char *pcsymbol, *rasymbol;
 
char *s = get_symtab_entry(istate->epc);
if (s)
pcsymbol = s;
s = get_symtab_entry(istate->ra);
if (s)
rasymbol = s;
printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol, istate->ra, rasymbol, istate->sp);
pcsymbol = symtab_fmt_name_lookup(istate->epc);
rasymbol = symtab_fmt_name_lookup(istate->ra);
 
printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol,
istate->ra, rasymbol, istate->sp);
}
 
static void unhandled_exception(int n, istate_t *istate)
/branches/dynload/kernel/arch/mips32/src/console.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup mips32
/** @addtogroup mips32
* @{
*/
/** @file
33,19 → 33,8
*/
 
#include <console/console.h>
#include <arch/console.h>
#include <arch/drivers/serial.h>
#include <arch/drivers/msim.h>
#include <genarch/fb/fb.h>
 
void console_init(devno_t devno)
{
if (serial_init())
serial_console(devno);
else
msim_console(devno);
}
 
/** Acquire console back for kernel
*
*/
54,7 → 43,6
#ifdef CONFIG_FB
fb_redraw();
#endif
msim_kbd_grab();
}
 
/** Return console to userspace
62,7 → 50,6
*/
void arch_release_console(void)
{
msim_kbd_release();
}
 
/** @}
/branches/dynload/kernel/arch/mips32/src/debugger.c
37,12 → 37,12
#include <memstr.h>
#include <console/kconsole.h>
#include <console/cmd.h>
#include <symtab.h>
#include <print.h>
#include <panic.h>
#include <arch.h>
#include <arch/cp0.h>
#include <func.h>
#include <symtab.h>
 
bpinfo_t breakpoints[BKPOINTS_MAX];
SPINLOCK_INITIALIZE(bkpoint_lock);
259,8 → 259,9
for (i = 0; i < BKPOINTS_MAX; i++)
if (breakpoints[i].address) {
symbol = get_symtab_entry(breakpoints[i].address);
symbol = symtab_fmt_name_lookup(
breakpoints[i].address);
 
printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i,
breakpoints[i].counter, breakpoints[i].address,
((breakpoints[i].flags & BKPOINT_INPROG) ? "true" :
348,9 → 349,10
if (cur->flags & BKPOINT_INPROG)
printf("Warning: breakpoint recursion\n");
if (!(cur->flags & BKPOINT_FUNCCALL))
if (!(cur->flags & BKPOINT_FUNCCALL)) {
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
get_symtab_entry(istate->epc));
symtab_fmt_name_lookup(istate->epc));
}
 
/* Return first instruction back */
((uint32_t *)cur->address)[0] = cur->instruction;
363,8 → 365,9
}
cur->flags |= BKPOINT_INPROG;
} else {
printf("***Breakpoint %p in %s.\n", fireaddr,
get_symtab_entry(fireaddr));
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr,
symtab_fmt_name_lookup(fireaddr));
 
/* Move on to next instruction */
istate->epc += 4;
}
384,7 → 387,7
atomic_set(&haltstate, 1);
spinlock_unlock(&bkpoint_lock);
kconsole("debug", "Debug console ready (type 'exit' to continue)\n", false);
kconsole("debug", "Debug console ready.\n", false);
spinlock_lock(&bkpoint_lock);
atomic_set(&haltstate, 0);
/branches/dynload/kernel/arch/mips32/src/mm/tlb.c
40,12 → 40,12
#include <arch/cp0.h>
#include <panic.h>
#include <arch.h>
#include <symtab.h>
#include <synch/mutex.h>
#include <print.h>
#include <debug.h>
#include <align.h>
#include <interrupt.h>
#include <symtab.h>
 
static void tlb_refill_fail(istate_t *);
static void tlb_invalid_fail(istate_t *);
320,19 → 320,14
 
void tlb_refill_fail(istate_t *istate)
{
char *symbol = "";
char *sym2 = "";
char *symbol, *sym2;
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
s = get_symtab_entry(istate->ra);
if (s)
sym2 = s;
 
symbol = symtab_fmt_name_lookup(istate->epc);
sym2 = symtab_fmt_name_lookup(istate->ra);
fault_if_from_uspace(istate, "TLB Refill Exception on %p.",
cp0_badvaddr_read());
panic("%x: TLB Refill Exception at %x(%s<-%s).", cp0_badvaddr_read(),
panic("%x: TLB Refill Exception at %x (%s<-%s).", cp0_badvaddr_read(),
istate->epc, symbol, sym2);
}
 
339,27 → 334,25
 
void tlb_invalid_fail(istate_t *istate)
{
char *symbol = "";
char *symbol;
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
symbol = symtab_fmt_name_lookup(istate->epc);
 
fault_if_from_uspace(istate, "TLB Invalid Exception on %p.",
cp0_badvaddr_read());
panic("%x: TLB Invalid Exception at %x(%s).", cp0_badvaddr_read(),
panic("%x: TLB Invalid Exception at %x (%s).", cp0_badvaddr_read(),
istate->epc, symbol);
}
 
void tlb_modified_fail(istate_t *istate)
{
char *symbol = "";
char *symbol;
 
char *s = get_symtab_entry(istate->epc);
if (s)
symbol = s;
symbol = symtab_fmt_name_lookup(istate->epc);
 
fault_if_from_uspace(istate, "TLB Modified Exception on %p.",
cp0_badvaddr_read());
panic("%x: TLB Modified Exception at %x(%s).", cp0_badvaddr_read(),
panic("%x: TLB Modified Exception at %x (%s).", cp0_badvaddr_read(),
istate->epc, symbol);
}
 
/branches/dynload/kernel/arch/mips32/src/mm/frame.c
40,22 → 40,22
#include <mm/asid.h>
#include <config.h>
#include <arch/drivers/msim.h>
#include <arch/drivers/serial.h>
#include <print.h>
 
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K
#define ZERO_FRAMES 2048
#define ZERO_PAGE_WIDTH 18 /* 256K */
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH)
#define ZERO_PAGE_ASID ASID_INVALID
#define ZERO_PAGE_TLBI 0
#define ZERO_PAGE_ADDR 0
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1)
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET])
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K
#define ZERO_FRAMES 2048
#define ZERO_PAGE_WIDTH 18 /* 256K */
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH)
#define ZERO_PAGE_ASID ASID_INVALID
#define ZERO_PAGE_TLBI 0
#define ZERO_PAGE_ADDR 0
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1)
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET])
 
#define ZERO_PAGE_VALUE_KSEG1(frame) (((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET])
#define ZERO_PAGE_VALUE_KSEG1(frame) \
(((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET])
 
#define MAX_REGIONS 32
#define MAX_REGIONS 32
 
typedef struct {
pfn_t start;
65,7 → 65,6
static count_t phys_regions_count = 0;
static phys_region_t phys_regions[MAX_REGIONS];
 
 
/** Check whether frame is available
*
* Returns true if given frame is generally available for use.
84,13 → 83,7
if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH))
return false;
#endif
 
#ifdef MACHINE_simics
/* Simics device (serial line) */
if (frame == (KA2PA(SERIAL_ADDRESS) >> ZERO_PAGE_WIDTH))
return false;
#endif
 
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul)
/* gxemul devices */
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
/branches/dynload/kernel/arch/mips32/src/mips32.c
52,10 → 52,14
#include <arch/debugger.h>
#include <genarch/fb/fb.h>
#include <genarch/fb/visuals.h>
#include <genarch/drivers/dsrln/dsrlnin.h>
#include <genarch/drivers/dsrln/dsrlnout.h>
#include <genarch/srln/srln.h>
#include <macros.h>
#include <ddi/device.h>
#include <config.h>
#include <string.h>
#include <arch/drivers/msim.h>
 
#include <arch/asm/regname.h>
 
132,7 → 136,7
void arch_post_mm_init(void)
{
interrupt_init();
console_init(device_assign_devno());
#ifdef CONFIG_FB
/* GXemul framebuffer */
fb_properties_t gxemul_prop = {
144,23 → 148,11
.visual = VISUAL_BGR_8_8_8,
};
fb_init(&gxemul_prop);
#endif
 
#ifdef MACHINE_msim
sysinfo_set_item_val("machine.msim", NULL, 1);
#endif
 
#ifdef MACHINE_simics
sysinfo_set_item_val("machine.simics", NULL, 1);
#endif
 
#ifdef MACHINE_bgxemul
sysinfo_set_item_val("machine.bgxemul", NULL, 1);
#endif
 
#ifdef MACHINE_lgxemul
sysinfo_set_item_val("machine.lgxemul", NULL, 1);
#endif
#else
#ifdef CONFIG_MIPS_PRN
dsrlnout_init((ioport8_t *) MSIM_KBD_ADDRESS);
#endif /* CONFIG_MIPS_PRN */
#endif /* CONFIG_FB */
}
 
void arch_post_cpu_init(void)
173,6 → 165,28
 
void arch_post_smp_init(void)
{
#ifdef CONFIG_MIPS_KBD
devno_t devno = device_assign_devno();
/*
* Initialize the msim/GXemul keyboard port. Then initialize the serial line
* module and connect it to the msim/GXemul keyboard. Enable keyboard interrupts.
*/
indev_t *kbrdin = dsrlnin_init((dsrlnin_t *) MSIM_KBD_ADDRESS, devno, MSIM_KBD_IRQ);
if (kbrdin) {
srln_init(kbrdin);
cp0_unmask_int(MSIM_KBD_IRQ);
}
/*
* This is the necessary evil until the userspace driver is entirely
* self-sufficient.
*/
sysinfo_set_item_val("kbd", NULL, true);
sysinfo_set_item_val("kbd.devno", NULL, devno);
sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ);
sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS);
#endif
}
 
void calibrate_delay_loop(void)
221,7 → 235,6
void arch_reboot(void)
{
___halt();
while (1);
}
 
/branches/dynload/kernel/arch/ia32/include/pm.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
35,61 → 35,59
#ifndef KERN_ia32_PM_H_
#define KERN_ia32_PM_H_
 
#define IDT_ITEMS 64
#define GDT_ITEMS 7
#define IDT_ITEMS 64
#define GDT_ITEMS 7
 
#define VESA_INIT_SEGMENT 0x8000
#define NULL_DES 0
#define KTEXT_DES 1
#define KDATA_DES 2
#define UTEXT_DES 3
#define UDATA_DES 4
#define TSS_DES 5
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */
 
#define NULL_DES 0
#define KTEXT_DES 1
#define KDATA_DES 2
#define UTEXT_DES 3
#define UDATA_DES 4
#define TSS_DES 5
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */
 
#ifdef CONFIG_FB
 
#define VESA_INIT_SEGMENT 0x8000
#define VESA_INIT_DES 7
#define VESA_INIT_SEGMENT 0x8000
#define VESA_INIT_DES 7
#define KTEXT32_DES KTEXT_DES
 
#undef GDT_ITEMS
#define GDT_ITEMS 8
#define GDT_ITEMS 8
 
#endif /* CONFIG_FB */
 
#define gdtselector(des) ((des) << 3)
 
#define selector(des) ((des) << 3)
#define PL_KERNEL 0
#define PL_USER 3
 
#define PL_KERNEL 0
#define PL_USER 3
#define AR_PRESENT (1 << 7)
#define AR_DATA (2 << 3)
#define AR_CODE (3 << 3)
#define AR_WRITABLE (1 << 1)
#define AR_INTERRUPT (0x0e)
#define AR_TSS (0x09)
 
#define AR_PRESENT (1 << 7)
#define AR_DATA (2 << 3)
#define AR_CODE (3 << 3)
#define AR_WRITABLE (1 << 1)
#define AR_INTERRUPT (0xe)
#define AR_TSS (0x9)
#define DPL_KERNEL (PL_KERNEL << 5)
#define DPL_USER (PL_USER << 5)
 
#define DPL_KERNEL (PL_KERNEL << 5)
#define DPL_USER (PL_USER << 5)
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */
 
#define TSS_BASIC_SIZE 104
#define TSS_IOMAP_SIZE (16 * 1024 + 1) /* 16K for bitmap + 1 terminating byte for convenience */
#define IO_PORTS (64 * 1024)
 
#define IO_PORTS (64 * 1024)
 
#ifndef __ASM__
 
#include <arch/types.h>
#include <arch/context.h>
 
struct ptr_16_32 {
typedef struct {
uint16_t limit;
uint32_t base;
} __attribute__ ((packed));
typedef struct ptr_16_32 ptr_16_32_t;
} __attribute__ ((packed)) ptr_16_32_t;
 
struct descriptor {
typedef struct {
unsigned limit_0_15: 16;
unsigned base_0_15: 16;
unsigned base_16_23: 8;
100,19 → 98,17
unsigned special: 1;
unsigned granularity : 1;
unsigned base_24_31: 8;
} __attribute__ ((packed));
typedef struct descriptor descriptor_t;
} __attribute__ ((packed)) descriptor_t;
 
struct idescriptor {
typedef struct {
unsigned offset_0_15: 16;
unsigned selector: 16;
unsigned unused: 8;
unsigned access: 8;
unsigned offset_16_31: 16;
} __attribute__ ((packed));
typedef struct idescriptor idescriptor_t;
} __attribute__ ((packed)) idescriptor_t;
 
struct tss {
typedef struct {
uint16_t link;
unsigned : 16;
uint32_t esp0;
152,13 → 148,12
unsigned : 16;
uint16_t iomap_base;
uint8_t iomap[TSS_IOMAP_SIZE];
} __attribute__ ((packed));
typedef struct tss tss_t;
} __attribute__ ((packed)) tss_t;
 
extern ptr_16_32_t gdtr;
extern ptr_16_32_t bootstrap_gdtr;
extern ptr_16_32_t protected_ap_gdtr;
extern struct tss *tss_p;
extern tss_t *tss_p;
 
extern descriptor_t gdt[];
 
/branches/dynload/kernel/arch/ia32/include/atomic.h
62,7 → 62,7
#else
asm volatile (
"decl %[count]\n"
: "+m" (val->count)
: [count] "+m" (val->count)
);
#endif /* CONFIG_SMP */
}
/branches/dynload/kernel/arch/ia32/include/asm.h
56,12 → 56,16
 
/** Halt CPU
*
* Halt the current CPU until interrupt event.
* Halt the current CPU.
*
*/
static inline void cpu_halt(void)
{
asm volatile ("hlt\n");
asm volatile (
"0:\n"
" hlt\n"
" jmp 0b\n"
);
}
 
static inline void cpu_sleep(void)
/branches/dynload/kernel/arch/ia32/include/cpu.h
55,7 → 55,7
unsigned int family;
unsigned int model;
unsigned int stepping;
struct tss *tss;
tss_t *tss;
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */
} cpu_arch_t;
/branches/dynload/kernel/arch/ia32/include/drivers/kbd.h
File deleted
/branches/dynload/kernel/arch/ia32/include/drivers/i8254.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
/branches/dynload/kernel/arch/ia32/include/drivers/vesa.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
/branches/dynload/kernel/arch/ia32/include/drivers/i8259.h
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
38,13 → 38,13
#include <arch/types.h>
#include <arch/interrupt.h>
 
#define PIC_PIC0PORT1 ((ioport8_t *) 0x20)
#define PIC_PIC0PORT2 ((ioport8_t *) 0x21)
#define PIC_PIC1PORT1 ((ioport8_t *) 0xa0)
#define PIC_PIC1PORT2 ((ioport8_t *) 0xa1)
#define PIC_PIC0PORT1 ((ioport8_t *) 0x20)
#define PIC_PIC0PORT2 ((ioport8_t *) 0x21)
#define PIC_PIC1PORT1 ((ioport8_t *) 0xa0)
#define PIC_PIC1PORT2 ((ioport8_t *) 0xa1)
 
#define PIC_NEEDICW4 (1<<0)
#define PIC_ICW1 (1<<4)
#define PIC_NEEDICW4 (1 << 0)
#define PIC_ICW1 (1 << 4)
 
extern void i8259_init(void);
extern void pic_enable_irqs(uint16_t irqmask);
/branches/dynload/kernel/arch/ia32/Makefile.inc
45,23 → 45,23
## Accepted CPUs
#
 
ifeq ($(MACHINE),athlon_xp)
ifeq ($(PROCESSOR),athlon_xp)
CMN2 = -march=athlon-xp
SUNCC_CFLAGS += -xarch=ssea
endif
ifeq ($(MACHINE),athlon_mp)
ifeq ($(PROCESSOR),athlon_mp)
CMN2 = -march=athlon-mp
SUNCC_CFLAGS += xarch=ssea
endif
ifeq ($(MACHINE),pentium3)
ifeq ($(PROCESSOR),pentium3)
CMN2 = -march=pentium3
SUNCC_CFLAGS += -xarch=sse
endif
ifeq ($(MACHINE),pentium4)
ifeq ($(PROCESSOR),pentium4)
CMN2 = -march=pentium4
SUNCC_CFLAGS += -xarch=sse2
endif
ifeq ($(MACHINE),core)
ifeq ($(PROCESSOR),core)
CMN2 = -march=prescott
SUNCC_CFLAGS += -xarch=sse3
endif
/branches/dynload/kernel/arch/ia32/src/ia32.c
44,7 → 44,8
#include <genarch/drivers/legacy/ia32/io.h>
#include <genarch/drivers/ega/ega.h>
#include <arch/drivers/vesa.h>
#include <genarch/kbd/i8042.h>
#include <genarch/drivers/i8042/i8042.h>
#include <genarch/kbrd/kbrd.h>
#include <arch/drivers/i8254.h>
#include <arch/drivers/i8259.h>
 
110,13 → 111,17
/* hard clock */
i8254_init();
 
#ifdef CONFIG_FB
if (vesa_present())
if (vesa_present())
vesa_init();
else
#endif
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */
#ifdef CONFIG_EGA
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */
#else
{}
#endif
/* Enable debugger */
debugger_init();
146,11 → 151,20
 
void arch_post_smp_init(void)
{
#ifdef CONFIG_PC_KBD
devno_t devno = device_assign_devno();
/* keyboard controller */
(void) i8042_init((i8042_t *) I8042_BASE, devno, IRQ_KBD);
 
/*
* Initialize the i8042 controller. Then initialize the keyboard
* module and connect it to i8042. Enable keyboard interrupts.
*/
indev_t *kbrdin = i8042_init((i8042_t *) I8042_BASE, devno, IRQ_KBD);
if (kbrdin) {
kbrd_init(kbrdin);
trap_virtual_enable_irqs(1 << IRQ_KBD);
}
/*
* This is the necessary evil until the userspace driver is entirely
* self-sufficient.
*/
161,6 → 175,7
(uintptr_t) I8042_BASE);
sysinfo_set_item_val("kbd.address.kernel", NULL,
(uintptr_t) I8042_BASE);
#endif
}
 
void calibrate_delay_loop(void)
194,9 → 209,14
void arch_grab_console(void)
{
#ifdef CONFIG_FB
vesa_redraw();
if (vesa_present())
vesa_redraw();
else
#endif
#ifdef CONFIG_EGA
ega_redraw();
#else
ega_redraw();
{}
#endif
}
 
/branches/dynload/kernel/arch/ia32/src/syscall.c
44,7 → 44,7
extern void sysenter_handler(void);
 
/* set kernel mode CS selector */
write_msr(IA32_MSR_SYSENTER_CS, selector(KTEXT_DES));
write_msr(IA32_MSR_SYSENTER_CS, gdtselector(KTEXT_DES));
/* set kernel mode entry point */
write_msr(IA32_MSR_SYSENTER_EIP, (uint32_t) sysenter_handler);
}
/branches/dynload/kernel/arch/ia32/src/pm.c
112,7 → 112,7
 
void tss_initialize(tss_t *t)
{
memsetb(t, sizeof(struct tss), 0);
memsetb(t, sizeof(tss_t), 0);
}
 
/*
127,7 → 127,7
d = &idt[i];
 
d->unused = 0;
d->selector = selector(KTEXT_DES);
d->selector = gdtselector(KTEXT_DES);
 
d->access = AR_PRESENT | AR_INTERRUPT; /* masking interrupt */
 
214,7 → 214,7
* As of this moment, the current CPU has its own GDT pointing
* to its own TSS. We just need to load the TR register.
*/
tr_load(selector(TSS_DES));
tr_load(gdtselector(TSS_DES));
clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels and clear NT flag. */
clean_AM_flag(); /* Disable alignment check */
/branches/dynload/kernel/arch/ia32/src/smp/smp.c
26,7 → 26,7
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
/** @addtogroup ia32
/** @addtogroup ia32
* @{
*/
/** @file
131,8 → 131,8
uint8_t apic = l_apic_id();
 
for (i = 0; i < ops->cpu_count(); i++) {
struct descriptor *gdt_new;
descriptor_t *gdt_new;
/*
* Skip processors marked unusable.
*/
159,14 → 159,14
* it needs to be replaced by a generic fuctionality of
* the memory subsystem
*/
gdt_new = (struct descriptor *) malloc(GDT_ITEMS *
sizeof(struct descriptor), FRAME_ATOMIC);
gdt_new = (descriptor_t *) malloc(GDT_ITEMS *
sizeof(descriptor_t), FRAME_ATOMIC);
if (!gdt_new)
panic("Cannot allocate memory for GDT.");
 
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor));
memsetb(&gdt_new[TSS_DES], sizeof(struct descriptor), 0);
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor);
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(descriptor_t));
memsetb(&gdt_new[TSS_DES], sizeof(descriptor_t), 0);
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(descriptor_t);
protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new);
gdtr.base = (uintptr_t) gdt_new;
 
/branches/dynload/kernel/arch/ia32/src/ddi/ddi.c
156,7 → 156,7
* type must be changed to describe inactive TSS.
*/
gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL;
tr_load(selector(TSS_DES));
tr_load(gdtselector(TSS_DES));
/*
* Update the generation count so that faults caused by
/branches/dynload/kernel/arch/ia32/src/proc/scheduler.c
59,14 → 59,14
{
uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE -
SP_DELTA];
 
/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */
write_msr(IA32_MSR_SYSENTER_ESP, kstk);
 
/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */
CPU->arch.tss->esp0 = kstk;
CPU->arch.tss->ss0 = selector(KDATA_DES);
 
CPU->arch.tss->ss0 = gdtselector(KDATA_DES);
/* Set up TLS in GS register */
set_tls_desc(THREAD->arch.tls);
}
/branches/dynload/kernel/arch/ia32/src/boot/vesa_ret.inc
0,0 → 1,12
.code32
vesa_init_protected:
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %fs
movw %cx, %gs
movw %cx, %ds # kernel data + stack
movw %cx, %ss
movl $START_STACK, %esp # initialize stack pointer
jmpl $gdtselector(KTEXT_DES), $vesa_meeting_point
/branches/dynload/kernel/arch/ia32/src/boot/boot.S
42,69 → 42,52
multiboot_header:
.long MULTIBOOT_HEADER_MAGIC
.long MULTIBOOT_HEADER_FLAGS
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) # checksum
.long multiboot_header
.long unmapped_ktext_start
.long 0
.long 0
.long multiboot_image_start
 
multiboot_image_start:
cld
movl $START_STACK, %esp # initialize stack pointer
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register
 
movw $selector(KDATA_DES), %cx
movl $START_STACK, %esp # initialize stack pointer
lgdt KA2PA(bootstrap_gdtr) # initialize Global Descriptor Table register
movw $gdtselector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %fs
movw %cx, %gs
movw %cx, %ds # kernel data + stack
movw %cx, %ds # kernel data + stack
movw %cx, %ss
jmpl $selector(KTEXT_DES), $multiboot_meeting_point
jmpl $gdtselector(KTEXT_DES), $multiboot_meeting_point
multiboot_meeting_point:
movl %eax, grub_eax # save parameters from GRUB
movl %eax, grub_eax # save parameters from GRUB
movl %ebx, grub_ebx
xorl %eax, %eax
cpuid
cmp $0x0, %eax # any function > 0?
xorl %eax, %eax
cpuid
cmp $0x0, %eax # any function > 0?
jbe pse_unsupported
movl $0x1, %eax # Basic function code 1
movl $0x1, %eax # basic function code 1
cpuid
bt $3, %edx # Test if PSE is supported
bt $3, %edx # test if PSE is supported
jc pse_supported
 
pse_unsupported:
movl $pse_msg, %esi
jmp error_halt
pse_supported:
#ifdef CONFIG_FB
mov $vesa_init, %esi
mov $VESA_INIT_SEGMENT << 4, %edi
mov $e_vesa_init - vesa_init, %ecx
rep movsb
 
mov $VESA_INIT_SEGMENT << 4, %edi
jmpl *%edi
#include "vesa_prot.inc"
 
# map kernel and turn paging on
call map_kernel
vesa_meeting_point:
mov %esi, KA2PA(vesa_ph_addr)
mov %di, KA2PA(vesa_height)
shr $16, %edi
mov %di, KA2PA(vesa_width)
mov %bx, KA2PA(vesa_scanline)
shr $16, %ebx
mov %bx, KA2PA(vesa_bpp)
#endif
 
call map_kernel # map kernel and turn paging on
 
# arch_pre_main(grub_eax, grub_ebx)
# call arch_pre_main(grub_eax, grub_ebx)
pushl grub_ebx
pushl grub_eax
call arch_pre_main
111,10 → 94,11
call main_bsp
# Not reached.
# not reached
cli
hlt
hlt0:
hlt
jmp hlt0
 
.global map_kernel
map_kernel:
123,8 → 107,8
# For simplicity, we map the entire 4G space.
#
movl %cr4, %ecx
orl $(1 << 4), %ecx # turn PSE on
andl $(~(1 << 5)), %ecx # turn PAE off
orl $(1 << 4), %ecx # turn PSE on
andl $(~(1 << 5)), %ecx # turn PAE off
movl %ecx, %cr4
movl $(page_directory + 0), %esi
131,30 → 115,31
movl $(page_directory + 2048), %edi
xorl %ecx, %ecx
xorl %ebx, %ebx
0:
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
orl %ebx, %eax
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
addl $(4 * 1024 * 1024), %ebx
 
incl %ecx
cmpl $512, %ecx
jl 0b
 
floop:
movl $((1 << 7) | (1 << 1) | (1 << 0)), %eax
orl %ebx, %eax
movl %eax, (%esi, %ecx, 4) # mapping 0x00000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
movl %eax, (%edi, %ecx, 4) # mapping 0x80000000 + %ecx * 4M => 0x00000000 + %ecx * 4M
addl $(4 * 1024 * 1024), %ebx
incl %ecx
cmpl $512, %ecx
jl floop
movl %esi, %cr3
movl %cr0, %ebx
orl $(1 << 31), %ebx # turn paging on
orl $(1 << 31), %ebx # turn paging on
movl %ebx, %cr0
ret
 
# Print string from %esi to EGA display (in red) and halt
error_halt:
movl $0xb8000, %edi # base of EGA text mode memory
movl $0xb8000, %edi # base of EGA text mode memory
xorl %eax, %eax
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
movw $0x3d4, %dx # read bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
162,7 → 147,7
inb %dx, %al
shl $8, %ax
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
movw $0x3d4, %dx # read bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
171,7 → 156,9
cmp $1920, %ax
jbe cursor_ok
movw $1920, %ax # sanity check for the cursor on the last line
movw $1920, %ax # sanity check for the cursor on the last line
cursor_ok:
movw %ax, %bx
178,7 → 165,7
shl $1, %eax
addl %eax, %edi
movw $0x0c00, %ax # black background, light red foreground
movw $0x0c00, %ax # black background, light red foreground
ploop:
lodsb
185,11 → 172,11
cmp $0, %al
je ploop_end
stosw
inc %bx
inc %bx
jmp ploop
ploop_end:
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
movw $0x3d4, %dx # write bits 8 - 15 of the cursor address
movb $0xe, %al
outb %al, %dx
197,7 → 184,7
movb %bh, %al
outb %al, %dx
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
movw $0x3d4, %dx # write bits 0 - 7 of the cursor address
movb $0xf, %al
outb %al, %dx
204,241 → 191,14
movw $0x3d5, %dx
movb %bl, %al
outb %al, %dx
cli
hlt
hlt1:
hlt
jmp hlt1
 
#ifdef CONFIG_FB
vesa_init:
jmp $selector(VESA_INIT_DES), $vesa_init_real - vesa_init
.code16
vesa_init_real:
mov %cr0, %eax
and $~1, %eax
mov %eax, %cr0
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
vesa_init_real2:
mov $VESA_INIT_SEGMENT, %bx
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
mov %bx, %ds
mov %bx, %ss
movl %esp, %eax
movl $0x0000fffc, %esp
movl $0x0000fffc, %ebp
pushl %eax
#define VESA_INFO_SIZE 1024
#include "vesa_real.inc"
 
#define VESA_MODE_ATTRIBUTES_OFFSET 0
#define VESA_MODE_LIST_PTR_OFFSET 14
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_WIDTH_OFFSET 18
#define VESA_MODE_HEIGHT_OFFSET 20
#define VESA_MODE_BPP_OFFSET 25
#define VESA_MODE_PHADDR_OFFSET 40
 
#define VESA_END_OF_MODES 0xffff
 
#define VESA_OK 0x4f
 
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
#define VESA_SET_PALETTE 0x4f09
 
#if CONFIG_VESA_BPP == 24
#define CONFIG_VESA_BPP_VARIANT 32
#endif
 
mov $VESA_GET_INFO, %ax
mov $e_vesa_init - vesa_init, %di
push %di
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
mov %si, %gs
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
add $VESA_INFO_SIZE, %di
 
1:# Try next mode
mov %gs:(%si), %cx
cmp $VESA_END_OF_MODES, %cx
jz 0f
inc %si
inc %si
push %cx
push %di
push %si
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %si
pop %di
pop %cx
cmp $VESA_OK, %al
jnz 0f
mov $CONFIG_VESA_WIDTH, %ax
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_HEIGHT, %ax
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
jnz 1b
mov $CONFIG_VESA_BPP, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
 
#ifdef CONFIG_VESA_BPP_VARIANT
jz 2f
mov $CONFIG_VESA_BPP_VARIANT, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
#endif
jnz 1b
 
2:
mov %cx, %bx
or $0xc000, %bx
push %di
mov $VESA_SET_MODE, %ax
int $0x10
pop %di
cmp $VESA_OK, %al
jnz 0f
 
#if CONFIG_VESA_BPP == 8
# Set 3:2:3 VGA palette
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
push %di
mov $vga323 - vesa_init, %di
mov $0x100, %ecx
bt $5, %ax # Test if VGA compatible registers are present
jnc vga_compat
# Try VESA routine to set palette
mov $VESA_SET_PALETTE, %ax
xor %bl, %bl
xor %dx, %dx
int $0x10
cmp $0x00, %ah
je vga_not_compat
vga_compat:
# Try VGA registers to set palette
movw $0x3c6, %dx # Set palette mask
movb $0xff, %al
outb %al, %dx
movw $0x3c8, %dx # First index to set
xor %al, %al
outb %al, %dx
movw $0x3c9, %dx # Data port
vga_loop:
movb %es:2(%di), %al
outb %al, %dx
movb %es:1(%di), %al
outb %al, %dx
movb %es:(%di), %al
outb %al, %dx
addw $4, %di
loop vga_loop
vga_not_compat:
pop %di
#endif
mov VESA_MODE_PHADDR_OFFSET(%di), %esi
mov VESA_MODE_WIDTH_OFFSET(%di), %ax
shl $16, %eax
mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
mov VESA_MODE_BPP_OFFSET(%di), %bl
xor %bh, %bh
shl $16, %ebx
mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
mov %eax, %edi
8:
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
jmp 9f
9:
ljmpl $selector(KTEXT_DES), $(vesa_init_protect - vesa_init + VESA_INIT_SEGMENT << 4)
 
0:# No prefered mode found
mov $0x111, %cx
push %di
push %cx
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %cx
pop %di
cmp $VESA_OK, %al
jnz 1f
jz 2b # Force relative jump
1:
mov $0x0003, %ax
int $0x10
mov $0xffffffff, %edi # EGA text mode used, because of problems with VESA
xor %ax, %ax
jz 8b # Force relative jump
 
vga323:
#include "vga323.pal"
 
.code32
vesa_init_protect:
movw $selector(KDATA_DES), %cx
movw %cx, %es
movw %cx, %fs
movw %cx, %gs
movw %cx, %ds # kernel data + stack
movw %cx, %ss
movl $START_STACK, %esp # initialize stack pointer
 
jmpl $selector(KTEXT_DES), $vesa_meeting_point
 
.align 4
e_vesa_init:
#endif
 
.section K_DATA_START, "aw", @progbits
 
.align 4096
/branches/dynload/kernel/arch/ia32/src/boot/vesa_real.inc
0,0 → 1,335
#ifdef CONFIG_FB
 
#include <macros.h>
 
#define VESA_INFO_SIZE 1024
 
#define VESA_MODE_ATTRIBUTES_OFFSET 0
#define VESA_MODE_LIST_PTR_OFFSET 14
#define VESA_MODE_SCANLINE_OFFSET 16
#define VESA_MODE_WIDTH_OFFSET 18
#define VESA_MODE_HEIGHT_OFFSET 20
#define VESA_MODE_BPP_OFFSET 25
#define VESA_MODE_PHADDR_OFFSET 40
 
#define VESA_END_OF_MODES 0xffff
 
#define VESA_OK 0x4f
 
#define VESA_GET_INFO 0x4f00
#define VESA_GET_MODE_INFO 0x4f01
#define VESA_SET_MODE 0x4f02
#define VESA_SET_PALETTE 0x4f09
 
.code32
vesa_init:
jmp $gdtselector(VESA_INIT_DES), $vesa_init_real - vesa_init
.code16
vesa_init_real:
mov %cr0, %eax
and $~1, %eax
mov %eax, %cr0
jmp $VESA_INIT_SEGMENT, $vesa_init_real2 - vesa_init
vesa_init_real2:
mov $VESA_INIT_SEGMENT, %bx
mov %bx, %es
mov %bx, %fs
mov %bx, %gs
mov %bx, %ds
mov %bx, %ss
movl %esp, %eax
movl $0x0000fffc, %esp
movl $0x0000fffc, %ebp
pushl %eax
# parse default mode string
mov $default_mode - vesa_init, %di
xor %eax, %eax
xor %ebx, %ebx
mov $8, %ecx
parse_width:
mov (%di), %al
# check for digit
cmp $'0', %al
jb parse_width_done
cmp $'9', %al
ja parse_width_done
sub $'0', %al
# multiply default_width by 10 and add digit
mov default_width - vesa_init, %bx
lea (%ebx, %ebx, 4), %ebx
shl $1, %ebx
add %ax, %bx
mov %bx, default_width - vesa_init
inc %di
loop parse_width
parse_width_done:
mov (%di), %al
cmp $0, %al
jz parse_done
inc %di
mov $8, %ecx
parse_height:
mov (%di), %al
# check for digit
cmp $'0', %al
jb parse_height_done
cmp $'9', %al
ja parse_height_done
sub $'0', %al
# multiply default_height by 10 and add digit
mov default_height - vesa_init, %bx
lea (%ebx, %ebx, 4), %ebx
shl $1, %ebx
add %ax, %bx
mov %bx, default_height - vesa_init
inc %di
loop parse_height
parse_height_done:
mov (%di), %al
cmp $0, %al
jz parse_done
inc %di
mov $4, %ecx
parse_bpp:
mov (%di), %al
# check for digit
cmp $'0', %al
jb parse_bpp_done
cmp $'9', %al
ja parse_bpp_done
sub $'0', %al
# multiply default_bpp by 10 and add digit
mov default_bpp - vesa_init, %bx
lea (%ebx, %ebx, 4), %ebx
shl $1, %ebx
add %ax, %bx
mov %bx, default_bpp - vesa_init
inc %di
loop parse_bpp
parse_bpp_done:
parse_done:
mov $VESA_GET_INFO, %ax
mov $e_vesa_init - vesa_init, %di
push %di
int $0x10
pop %di
cmp $VESA_OK, %al
jnz no_mode
mov 2 + VESA_MODE_LIST_PTR_OFFSET(%di), %si
mov %si, %gs
mov VESA_MODE_LIST_PTR_OFFSET(%di), %si
add $VESA_INFO_SIZE, %di
next_mode:
# try next mode
mov %gs:(%si), %cx
cmp $VESA_END_OF_MODES, %cx
jz no_mode
inc %si
inc %si
push %cx
push %di
push %si
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %si
pop %di
pop %cx
cmp $VESA_OK, %al
jnz no_mode
mov default_width - vesa_init, %ax
cmp VESA_MODE_WIDTH_OFFSET(%di), %ax
jnz next_mode
mov default_height - vesa_init, %ax
cmp VESA_MODE_HEIGHT_OFFSET(%di), %ax
jnz next_mode
mov default_bpp - vesa_init, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
jz set_mode
mov $24, %al
cmp default_bpp - vesa_init, %al
jnz next_mode
# for 24 bpp modes accept also 32 bit bpp
mov $32, %al
cmp VESA_MODE_BPP_OFFSET(%di), %al
jnz next_mode
set_mode:
mov %cx, %bx
or $0xc000, %bx
push %di
mov $VESA_SET_MODE, %ax
int $0x10
pop %di
cmp $VESA_OK, %al
jnz no_mode
# set 3:2:3 VGA palette
mov VESA_MODE_BPP_OFFSET(%di), %al
cmp $8, %al
jnz vga_not_set
mov VESA_MODE_ATTRIBUTES_OFFSET(%di), %ax
push %di
mov $vga323 - vesa_init, %di
mov $0x100, %ecx
bt $5, %ax # test if VGA compatible registers are present
jnc vga_compat
# try VESA routine to set palette
mov $VESA_SET_PALETTE, %ax
xor %bl, %bl
xor %dx, %dx
int $0x10
cmp $0x00, %ah
je vga_not_compat
vga_compat:
# try VGA registers to set palette
movw $0x3c6, %dx # set palette mask
movb $0xff, %al
outb %al, %dx
movw $0x3c8, %dx # first index to set
xor %al, %al
outb %al, %dx
movw $0x3c9, %dx # data port
vga_loop:
movb %es:2(%di), %al
outb %al, %dx
movb %es:1(%di), %al
outb %al, %dx
movb %es:(%di), %al
outb %al, %dx
addw $4, %di
loop vga_loop
vga_not_compat:
pop %di
vga_not_set:
mov VESA_MODE_PHADDR_OFFSET(%di), %esi
mov VESA_MODE_WIDTH_OFFSET(%di), %ax
shl $16, %eax
mov VESA_MODE_HEIGHT_OFFSET(%di), %ax
mov VESA_MODE_BPP_OFFSET(%di), %bl
xor %bh, %bh
shl $16, %ebx
mov VESA_MODE_SCANLINE_OFFSET(%di), %bx
mov %eax, %edi
vesa_leave_real:
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
jmp vesa_leave_real2
vesa_leave_real2:
ljmpl $gdtselector(KTEXT32_DES), $(vesa_init_protected - vesa_init + VESA_INIT_SEGMENT << 4)
no_mode:
# no prefered mode found
mov $0x111, %cx
push %di
push %cx
mov $VESA_GET_MODE_INFO, %ax
int $0x10
pop %cx
pop %di
cmp $VESA_OK, %al
jnz text_mode
jz set_mode # force relative jump
text_mode:
# reset to EGA text mode (because of problems with VESA)
mov $0x0003, %ax
int $0x10
mov $0xffffffff, %edi
xor %ax, %ax
jz vesa_leave_real # force relative jump
 
vga323:
#include "vga323.pal"
 
default_width:
.word 0
 
default_height:
.word 0
 
default_bpp:
.byte 0
 
default_mode:
.ascii STRING(CONFIG_VESA_MODE)
.ascii "-"
.asciz STRING(CONFIG_VESA_BPP)
.fill 24
 
#include "vesa_ret.inc"
 
.align 4
e_vesa_init:
#endif
/branches/dynload/kernel/arch/ia32/src/boot/vesa_prot.inc
0,0 → 1,83
#ifdef CONFIG_FB
 
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002
#define MBINFO_BIT_CMDLINE 2
#define MBINFO_OFFSET_CMDLINE 16
 
# copy real mode VESA initialization code
mov $vesa_init, %esi
mov $VESA_INIT_SEGMENT << 4, %edi
mov $e_vesa_init - vesa_init, %ecx
rep movsb
# check for GRUB command line
mov grub_eax, %eax
cmp $MULTIBOOT_LOADER_MAGIC, %eax
jne no_cmdline
mov grub_ebx, %ebx
mov (%ebx), %eax
bt $MBINFO_BIT_CMDLINE, %eax
jnc no_cmdline
# skip the kernel path in command line
mov MBINFO_OFFSET_CMDLINE(%ebx), %esi
skip_loop:
lodsb
cmp $0, %al
je no_cmdline
cmp $' ', %al
je skip_loop_done
jmp skip_loop
skip_loop_done:
mov (%esi), %al
cmp $0, %al
je no_cmdline
# copy at most 23 characters from command line
mov $VESA_INIT_SEGMENT << 4, %edi
add $default_mode - vesa_init, %edi
mov $23, %ecx
cmd_loop:
lodsb
stosb
cmp $0, %al
je cmd_loop_done
loop cmd_loop
cmd_loop_done:
# zero termination
xor %eax, %eax
stosb
no_cmdline:
# jump to the real mode
mov $VESA_INIT_SEGMENT << 4, %edi
jmpl *%edi
vesa_meeting_point:
# returned back to protected mode
mov %esi, KA2PA(vesa_ph_addr)
mov %di, KA2PA(vesa_height)
shr $16, %edi
mov %di, KA2PA(vesa_width)
mov %bx, KA2PA(vesa_scanline)
shr $16, %ebx
mov %bx, KA2PA(vesa_bpp)
#endif
/branches/dynload/kernel/arch/ia32/src/userspace.c
74,13 → 74,13
"iret\n"
:
: [udata_des] "i" (selector(UDATA_DES) | PL_USER),
: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER),
[stack_size] "r" ((uint8_t *) kernel_uarg->uspace_stack + THREAD_STACK_SIZE),
[ipl] "r" (ipl),
[utext_des] "i" (selector(UTEXT_DES) | PL_USER),
[utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER),
[entry] "r" (kernel_uarg->uspace_entry),
[uarg] "r" (kernel_uarg->uspace_uarg),
[tls_des] "r" (selector(TLS_DES))
[tls_des] "r" (gdtselector(TLS_DES))
: "eax");
/* Unreachable */
/branches/dynload/kernel/arch/ia32/src/interrupt.c
44,7 → 44,6
#include <mm/tlb.h>
#include <mm/as.h>
#include <arch.h>
#include <symtab.h>
#include <proc/thread.h>
#include <proc/task.h>
#include <synch/spinlock.h>
52,6 → 51,7
#include <ipc/sysipc.h>
#include <interrupt.h>
#include <ddi/irq.h>
#include <symtab.h>
 
/*
* Interrupt and exception dispatching.
63,10 → 63,9
 
void decode_istate(istate_t *istate)
{
char *symbol = get_symtab_entry(istate->eip);
char *symbol;
 
if (!symbol)
symbol = "";
symbol = symtab_fmt_name_lookup(istate->eip);
 
if (CPU)
printf("----------------EXCEPTION OCCURED (cpu%u)----------------\n", CPU->id);
/branches/dynload/kernel/arch/ia32/src/drivers/vesa.c
58,10 → 58,9
 
int vesa_present(void)
{
if (vesa_width != 0xffff)
if ((vesa_width != 0xffff) && (vesa_height != 0xffff))
return true;
if (vesa_height != 0xffff)
return true;
return false;
}