/branches/dynload/kernel/test/fpu/sse1.c |
---|
58,14 → 58,14 |
for (i = 0; i < ATTEMPTS; i++) { |
asm volatile ( |
"movlpd %0, %%xmm2\n" |
: "=m" (arg) |
"movlpd %[arg], %%xmm2\n" |
: [arg] "=m" (arg) |
); |
delay(DELAY); |
asm volatile ( |
"movlpd %%xmm2, %0\n" |
: "=m" (after_arg) |
"movlpd %%xmm2, %[after_arg]\n" |
: [after_arg] "=m" (after_arg) |
); |
if (arg != after_arg) { |
90,14 → 90,14 |
for (i = 0; i < ATTEMPTS; i++) { |
asm volatile ( |
"movlpd %0, %%xmm2\n" |
: "=m" (arg) |
"movlpd %[arg], %%xmm2\n" |
: [arg] "=m" (arg) |
); |
scheduler(); |
asm volatile ( |
"movlpd %%xmm2, %0\n" |
: "=m" (after_arg) |
"movlpd %%xmm2, %[after_arg]\n" |
: [after_arg] "=m" (after_arg) |
); |
if (arg != after_arg) { |
/branches/dynload/kernel/genarch/include/drivers/ega/ega.h |
---|
36,6 → 36,7 |
#define KERN_EGA_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#define EGA_COLS 80 |
#define EGA_ROWS 25 |
/branches/dynload/kernel/genarch/include/multiboot/multiboot.h |
---|
0,0 → 1,100 |
/* |
* Copyright (c) 2009 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_MULTIBOOT_H_ |
#define KERN_MULTIBOOT_H_ |
#include <arch/types.h> |
#include <arch/boot/memmap.h> |
/** Multiboot 32-bit address. */ |
typedef uint32_t mbaddr_t; |
/** Multiboot mod structure */ |
typedef struct { |
mbaddr_t start; |
mbaddr_t end; |
mbaddr_t string; |
uint32_t reserved; |
} __attribute__ ((packed)) multiboot_mod_t; |
/** Multiboot mmap structure */ |
typedef struct { |
uint32_t size; |
e820memmap_t mm_info; |
} __attribute__ ((packed)) multiboot_mmap_t; |
/** Multiboot information structure */ |
typedef struct { |
uint32_t flags; |
uint32_t mem_lower; |
uint32_t mem_upper; |
uint32_t boot_device; |
uint32_t cmdline; |
uint32_t mods_count; |
mbaddr_t mods_addr; |
uint32_t syms[4]; |
uint32_t mmap_length; |
mbaddr_t mmap_addr; |
/* ... */ |
} __attribute__ ((packed)) multiboot_info_t; |
enum multiboot_info_flags { |
MBINFO_FLAGS_MEM = 0x01, |
MBINFO_FLAGS_BOOT = 0x02, |
MBINFO_FLAGS_CMDLINE = 0x04, |
MBINFO_FLAGS_MODS = 0x08, |
MBINFO_FLAGS_SYMS1 = 0x10, |
MBINFO_FLAGS_SYMS2 = 0x20, |
MBINFO_FLAGS_MMAP = 0x40 |
/* ... */ |
}; |
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002 |
/** Convert 32-bit multiboot address to a pointer. */ |
#define MULTIBOOT_PTR(mba) ((void *)(uintptr_t) (mba)) |
extern void multiboot_info_parse(uint32_t, const multiboot_info_t *); |
#endif |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/dynload/kernel/genarch/Makefile.inc |
---|
101,6 → 101,11 |
genarch/src/ofw/upa.c |
endif |
ifeq ($(CONFIG_MULTIBOOT), y) |
GENARCH_SOURCES += \ |
genarch/src/multiboot/multiboot.c |
endif |
ifeq ($(CONFIG_EGA), y) |
GENARCH_SOURCES += \ |
genarch/src/drivers/ega/ega.c |
/branches/dynload/kernel/genarch/src/ofw/ebus.c |
---|
38,7 → 38,7 |
#include <genarch/ofw/ofw_tree.h> |
#include <arch/memstr.h> |
#include <arch/trap/interrupt.h> |
#include <func.h> |
#include <string.h> |
#include <panic.h> |
#include <debug.h> |
#include <macros.h> |
/branches/dynload/kernel/genarch/src/ofw/fhc.c |
---|
38,7 → 38,7 |
#include <genarch/ofw/ofw_tree.h> |
#include <arch/drivers/fhc.h> |
#include <arch/memstr.h> |
#include <func.h> |
#include <string.h> |
#include <panic.h> |
#include <macros.h> |
/branches/dynload/kernel/genarch/src/ofw/ofw_tree.c |
---|
38,7 → 38,7 |
#include <genarch/ofw/ofw_tree.h> |
#include <arch/memstr.h> |
#include <mm/slab.h> |
#include <func.h> |
#include <string.h> |
#include <print.h> |
#include <panic.h> |
/branches/dynload/kernel/genarch/src/ofw/pci.c |
---|
39,7 → 39,7 |
#include <arch/drivers/pci.h> |
#include <arch/trap/interrupt.h> |
#include <arch/memstr.h> |
#include <func.h> |
#include <string.h> |
#include <panic.h> |
#include <macros.h> |
/branches/dynload/kernel/genarch/src/drivers/ega/ega.c |
---|
60,6 → 60,8 |
static uint8_t *backbuf; |
static ioport8_t *ega_base; |
#define EMPTY_CHAR 0x0720 |
chardev_t ega_console; |
/* |
69,13 → 71,13 |
{ |
if (ega_cursor < EGA_SCREEN) |
return; |
memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2), |
(EGA_SCREEN - EGA_COLS) * 2); |
memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2), |
(EGA_SCREEN - EGA_COLS) * 2); |
memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, 0x0720); |
memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, 0x0720); |
memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); |
memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); |
ega_cursor = ega_cursor - EGA_COLS; |
} |
103,9 → 105,16 |
uint8_t lo = pio_read_8(ega_base + EGA_DATA_REG); |
ega_cursor = (hi << 8) | lo; |
if (ega_cursor >= EGA_SCREEN) |
ega_cursor = 0; |
if ((ega_cursor % EGA_COLS) != 0) |
ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS; |
memsetw(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR); |
memsetw(backbuf + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR); |
ega_check_cursor(); |
ega_move_cursor(); |
ega_show_cursor(); |
119,7 → 128,7 |
videoram[ega_cursor * 2] = ch; |
} |
static void ega_putchar(chardev_t *d __attribute__((unused)), const char ch, bool silent) |
static void ega_putchar(chardev_t *dev __attribute__((unused)), const char ch, bool silent) |
{ |
ipl_t ipl; |
/branches/dynload/kernel/genarch/src/multiboot/multiboot.c |
---|
0,0 → 1,148 |
/* |
* Copyright (c) 2009 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
*/ |
#include <genarch/multiboot/multiboot.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <config.h> |
#include <string.h> |
#include <macros.h> |
/** Extract command name from the multiboot module command line. |
* |
* @param buf Destination buffer (will always null-terminate). |
* @param n Size of destination buffer. |
* @param cmd_line Input string (the command line). |
* |
*/ |
static void extract_command(char *buf, size_t n, const char *cmd_line) |
{ |
const char *start, *end, *cp; |
size_t max_len; |
/* Find the first space. */ |
end = strchr(cmd_line, ' '); |
if (end == NULL) |
end = cmd_line + strlen(cmd_line); |
/* |
* Find last occurence of '/' before 'end'. If found, place start at |
* next character. Otherwise, place start at beginning of buffer. |
*/ |
cp = end; |
start = buf; |
while (cp != start) { |
if (*cp == '/') { |
start = cp + 1; |
break; |
} |
--cp; |
} |
/* Copy the command and null-terminate the string. */ |
max_len = min(n - 1, (size_t) (end - start)); |
strncpy(buf, start, max_len + 1); |
buf[max_len] = '\0'; |
} |
/** Parse multiboot information structure. |
* |
* If @a signature does not contain a valid multiboot signature, |
* assumes no multiboot information is available. |
* |
* @param signature Should contain the multiboot signature. |
* @param mi Pointer to the multiboot information structure. |
*/ |
void multiboot_info_parse(uint32_t signature, const multiboot_info_t *mi) |
{ |
uint32_t flags; |
multiboot_mod_t *mods; |
uint32_t i; |
if (signature == MULTIBOOT_LOADER_MAGIC) |
flags = mi->flags; |
else { |
/* No multiboot info available. */ |
flags = 0; |
} |
/* Copy module information. */ |
if ((flags & MBINFO_FLAGS_MODS) != 0) { |
init.cnt = mi->mods_count; |
mods = (multiboot_mod_t *) MULTIBOOT_PTR(mi->mods_addr); |
for (i = 0; i < init.cnt; i++) { |
init.tasks[i].addr = PA2KA(mods[i].start); |
init.tasks[i].size = mods[i].end - mods[i].start; |
/* Copy command line, if available. */ |
if (mods[i].string) { |
extract_command(init.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN, |
MULTIBOOT_PTR(mods[i].string)); |
} else |
init.tasks[i].name[0] = '\0'; |
} |
} else |
init.cnt = 0; |
/* Copy memory map. */ |
int32_t mmap_length; |
multiboot_mmap_t *mme; |
uint32_t size; |
if ((flags & MBINFO_FLAGS_MMAP) != 0) { |
mmap_length = mi->mmap_length; |
mme = MULTIBOOT_PTR(mi->mmap_addr); |
e820counter = 0; |
i = 0; |
while (mmap_length > 0) { |
e820table[i++] = mme->mm_info; |
/* Compute address of next structure. */ |
size = sizeof(mme->size) + mme->size; |
mme = ((void *) mme) + size; |
mmap_length -= size; |
} |
e820counter = i; |
} else |
e820counter = 0; |
} |
/** @} |
*/ |
Property changes: |
Added: svn:mergeinfo |
/branches/dynload/kernel/generic/include/func.h |
---|
41,11 → 41,6 |
extern atomic_t haltstate; |
extern void halt(void); |
extern size_t strlen(const char *str); |
extern int strcmp(const char *src, const char *dst); |
extern int strncmp(const char *src, const char *dst, size_t len); |
extern void strncpy(char *dest, const char *src, size_t len); |
extern unative_t atoi(const char *text); |
extern void order(const uint64_t val, uint64_t *rv, char *suffix); |
/branches/dynload/kernel/generic/include/string.h |
---|
0,0 → 1,50 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_STRING_H_ |
#define KERN_STRING_H_ |
#include <arch/types.h> |
extern size_t strlen(const char *str); |
extern int strcmp(const char *src, const char *dst); |
extern int strncmp(const char *src, const char *dst, size_t len); |
extern void strncpy(char *dest, const char *src, size_t len); |
extern char *strchr(const char *s, int i); |
#endif |
/** @} |
*/ |
/branches/dynload/kernel/generic/include/memstr.h |
---|
46,8 → 46,6 |
extern void _memsetw(void *dst, size_t cnt, uint16_t x); |
extern void *memmove(void *dst, const void *src, size_t cnt); |
extern char *strcpy(char *dest, const char *src); |
#endif |
/** @} |
/branches/dynload/kernel/generic/include/typedefs.h |
---|
51,6 → 51,10 |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
#endif |
/** @} |
/branches/dynload/kernel/generic/src/main/kinit.c |
---|
32,7 → 32,7 |
/** |
* @file |
* @brief Kernel initialization thread. |
* @brief Kernel initialization thread. |
* |
* This file contains kinit kernel thread which carries out |
* high level system initialization. |
64,6 → 64,8 |
#include <security/cap.h> |
#include <lib/rd.h> |
#include <ipc/ipc.h> |
#include <debug.h> |
#include <string.h> |
#ifdef CONFIG_SMP |
#include <smp/smp.h> |
78,6 → 80,9 |
static char alive[ALIVE_CHARS] = "-\\|/"; |
#endif |
#define INIT_PREFIX "init:" |
#define INIT_PREFIX_LEN 5 |
/** Kernel initialization thread. |
* |
* kinit takes care of higher level kernel |
92,15 → 97,15 |
#if defined(CONFIG_SMP) || defined(CONFIG_KCONSOLE) |
thread_t *thread; |
#endif |
/* |
* Detach kinit as nobody will call thread_join_timeout() on it. |
*/ |
thread_detach(THREAD); |
interrupts_disable(); |
#ifdef CONFIG_SMP |
#ifdef CONFIG_SMP |
if (config.cpu_count > 1) { |
waitq_initialize(&ap_completion_wq); |
/* |
120,9 → 125,7 |
thread_join(thread); |
thread_detach(thread); |
} |
#endif /* CONFIG_SMP */ |
#ifdef CONFIG_SMP |
if (config.cpu_count > 1) { |
count_t i; |
138,7 → 141,6 |
thread_ready(thread); |
} else |
printf("Unable to create kcpulb thread for cpu" PRIc "\n", i); |
} |
} |
#endif /* CONFIG_SMP */ |
147,7 → 149,7 |
* At this point SMP, if present, is configured. |
*/ |
arch_post_smp_init(); |
#ifdef CONFIG_KCONSOLE |
if (stdin) { |
/* |
174,12 → 176,26 |
printf("init[%" PRIc "].addr is not frame aligned\n", i); |
continue; |
} |
char *name = init.tasks[i].name; |
if (name[0] == '\0') name = "init-bin"; |
/* |
* Construct task name from the 'init:' prefix and the |
* name stored in the init structure (if any). |
*/ |
char namebuf[TASK_NAME_BUFLEN]; |
char *name; |
name = init.tasks[i].name; |
if (name[0] == '\0') |
name = "<unknown>"; |
ASSERT(TASK_NAME_BUFLEN >= INIT_PREFIX_LEN); |
strncpy(namebuf, INIT_PREFIX, TASK_NAME_BUFLEN); |
strncpy(namebuf + INIT_PREFIX_LEN, name, |
TASK_NAME_BUFLEN - INIT_PREFIX_LEN); |
int rc = program_create_from_image((void *) init.tasks[i].addr, |
name, &programs[i]); |
namebuf, &programs[i]); |
if ((rc == 0) && (programs[i].task != NULL)) { |
/* |
202,15 → 218,21 |
} |
/* |
* Run user tasks with reasonable delays |
* Run user tasks with small delays |
* to avoid intermixed klog output. |
* |
* TODO: This certainly does not guarantee |
* anything, it just works in most of the |
* cases. Some better way how to achieve |
* nice klog output should be found. |
*/ |
for (i = 0; i < init.cnt; i++) { |
if (programs[i].task != NULL) { |
thread_usleep(50000); |
program_ready(&programs[i]); |
thread_usleep(10000); |
} |
} |
#ifdef CONFIG_KCONSOLE |
if (!stdin) { |
thread_sleep(10); |
/branches/dynload/kernel/generic/src/debug/symtab.c |
---|
37,7 → 37,7 |
#include <symtab.h> |
#include <byteorder.h> |
#include <func.h> |
#include <string.h> |
#include <print.h> |
#include <arch/types.h> |
#include <typedefs.h> |
/branches/dynload/kernel/generic/src/console/cmd.c |
---|
50,6 → 50,7 |
#include <arch.h> |
#include <config.h> |
#include <func.h> |
#include <string.h> |
#include <macros.h> |
#include <debug.h> |
#include <symtab.h> |
/branches/dynload/kernel/generic/src/console/kconsole.c |
---|
49,6 → 49,7 |
#include <macros.h> |
#include <debug.h> |
#include <func.h> |
#include <string.h> |
#include <symtab.h> |
#include <macros.h> |
#include <sysinfo/sysinfo.h> |
/branches/dynload/kernel/generic/src/printf/printf_core.c |
---|
40,7 → 40,7 |
#include <print.h> |
#include <arch/arg.h> |
#include <macros.h> |
#include <func.h> |
#include <string.h> |
#include <arch.h> |
/** show prefixes 0x or 0 */ |
/branches/dynload/kernel/generic/src/proc/task.c |
---|
52,6 → 52,7 |
#include <print.h> |
#include <errno.h> |
#include <func.h> |
#include <string.h> |
#include <syscall/copy.h> |
/** Spinlock protecting the tasks_tree AVL tree. */ |
273,7 → 274,7 |
return (unative_t) rc; |
namebuf[name_len] = '\0'; |
strcpy(TASK->name, namebuf); |
strncpy(TASK->name, namebuf, TASK_NAME_BUFLEN); |
return EOK; |
} |
/branches/dynload/kernel/generic/src/lib/string.c |
---|
0,0 → 1,170 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
* @{ |
*/ |
/** |
* @file |
* @brief Miscellaneous functions. |
*/ |
#include <string.h> |
#include <print.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <arch.h> |
#include <console/kconsole.h> |
/** Return number of characters in a string. |
* |
* @param str NULL terminated string. |
* |
* @return Number of characters in str. |
* |
*/ |
size_t strlen(const char *str) |
{ |
int i; |
for (i = 0; str[i]; i++); |
return i; |
} |
/** Compare two NULL terminated strings |
* |
* Do a char-by-char comparison of two NULL terminated strings. |
* The strings are considered equal iff they consist of the same |
* characters on the minimum of their lengths. |
* |
* @param src First string to compare. |
* @param dst Second string to compare. |
* |
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller. |
* |
*/ |
int strcmp(const char *src, const char *dst) |
{ |
for (; *src && *dst; src++, dst++) { |
if (*src < *dst) |
return -1; |
if (*src > *dst) |
return 1; |
} |
if (*src == *dst) |
return 0; |
if (!*src) |
return -1; |
return 1; |
} |
/** Compare two NULL terminated strings |
* |
* Do a char-by-char comparison of two NULL terminated strings. |
* The strings are considered equal iff they consist of the same |
* characters on the minimum of their lengths and specified maximal |
* length. |
* |
* @param src First string to compare. |
* @param dst Second string to compare. |
* @param len Maximal length for comparison. |
* |
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller. |
* |
*/ |
int strncmp(const char *src, const char *dst, size_t len) |
{ |
unsigned int i; |
for (i = 0; (*src) && (*dst) && (i < len); src++, dst++, i++) { |
if (*src < *dst) |
return -1; |
if (*src > *dst) |
return 1; |
} |
if (i == len || *src == *dst) |
return 0; |
if (!*src) |
return -1; |
return 1; |
} |
/** Copy NULL terminated string. |
* |
* Copy at most 'len' characters from string 'src' to 'dest'. |
* If 'src' is shorter than 'len', '\0' is inserted behind the |
* last copied character. |
* |
* @param src Source string. |
* @param dest Destination buffer. |
* @param len Size of destination buffer. |
* |
*/ |
void strncpy(char *dest, const char *src, size_t len) |
{ |
unsigned int i; |
for (i = 0; i < len; i++) { |
if (!(dest[i] = src[i])) |
return; |
} |
dest[i - 1] = '\0'; |
} |
/** Find first occurence of character in string. |
* |
* @param s String to search. |
* @param i Character to look for. |
* |
* @return Pointer to character in @a s or NULL if not found. |
*/ |
extern char *strchr(const char *s, int i) |
{ |
while (*s != '\0') { |
if (*s == i) |
return (char *) s; |
++s; |
} |
return NULL; |
} |
/** @} |
*/ |
/branches/dynload/kernel/generic/src/lib/memstr.c |
---|
160,25 → 160,5 |
p[i] = x; |
} |
/** Copy string. |
* |
* Copy string from src address to dst address. The copying is done |
* char-by-char until the null character. The source and destination memory |
* areas cannot overlap. |
* |
* @param src Source string to copy from. |
* @param dst Destination string to copy to. |
* |
* @return Address of the destination string. |
*/ |
char *strcpy(char *dest, const char *src) |
{ |
char *orig = dest; |
while ((*(dest++) = *(src++))) |
; |
return orig; |
} |
/** @} |
*/ |
/branches/dynload/kernel/generic/src/lib/func.c |
---|
77,103 → 77,6 |
cpu_halt(); |
} |
/** Return number of characters in a string. |
* |
* @param str NULL terminated string. |
* |
* @return Number of characters in str. |
*/ |
size_t strlen(const char *str) |
{ |
int i; |
for (i = 0; str[i]; i++) |
; |
return i; |
} |
/** Compare two NULL terminated strings |
* |
* Do a char-by-char comparison of two NULL terminated strings. |
* The strings are considered equal iff they consist of the same |
* characters on the minimum of their lengths. |
* |
* @param src First string to compare. |
* @param dst Second string to compare. |
* |
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller. |
* |
*/ |
int strcmp(const char *src, const char *dst) |
{ |
for (; *src && *dst; src++, dst++) { |
if (*src < *dst) |
return -1; |
if (*src > *dst) |
return 1; |
} |
if (*src == *dst) |
return 0; |
if (!*src) |
return -1; |
return 1; |
} |
/** Compare two NULL terminated strings |
* |
* Do a char-by-char comparison of two NULL terminated strings. |
* The strings are considered equal iff they consist of the same |
* characters on the minimum of their lengths and specified maximal |
* length. |
* |
* @param src First string to compare. |
* @param dst Second string to compare. |
* @param len Maximal length for comparison. |
* |
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller. |
* |
*/ |
int strncmp(const char *src, const char *dst, size_t len) |
{ |
unsigned int i; |
for (i = 0; (*src) && (*dst) && (i < len); src++, dst++, i++) { |
if (*src < *dst) |
return -1; |
if (*src > *dst) |
return 1; |
} |
if (i == len || *src == *dst) |
return 0; |
if (!*src) |
return -1; |
return 1; |
} |
/** Copy NULL terminated string. |
* |
* Copy at most 'len' characters from string 'src' to 'dest'. |
* If 'src' is shorter than 'len', '\0' is inserted behind the |
* last copied character. |
* |
* @param src Source string. |
* @param dest Destination buffer. |
* @param len Size of destination buffer. |
*/ |
void strncpy(char *dest, const char *src, size_t len) |
{ |
unsigned int i; |
for (i = 0; i < len; i++) { |
if (!(dest[i] = src[i])) |
return; |
} |
dest[i-1] = '\0'; |
} |
/** Convert ascii representation to unative_t |
* |
* Supports 0x for hexa & 0 for octal notation. |
/branches/dynload/kernel/generic/src/ipc/sysipc.c |
---|
936,6 → 936,11 |
/* Include phone address('id') of the caller in the request, |
* copy whole call->data, not only call->data.args */ |
if (STRUCT_TO_USPACE(calldata, &call->data)) { |
/* XXX |
* To avoid deadlocks in synchronous calls |
* this should be replaced by discarding |
* the call and notifying the caller. |
*/ |
return 0; |
} |
return (unative_t)call; |
/branches/dynload/kernel/Makefile |
---|
185,6 → 185,7 |
generic/src/lib/func.c \ |
generic/src/lib/memstr.c \ |
generic/src/lib/sort.c \ |
generic/src/lib/string.c \ |
generic/src/lib/elf.c \ |
generic/src/lib/rd.c \ |
generic/src/printf/printf_core.c \ |
/branches/dynload/kernel/arch/sparc64/include/types.h |
---|
57,10 → 57,6 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
typedef struct { |
} fncptr_t; |
/branches/dynload/kernel/arch/sparc64/include/boot/boot.h |
---|
48,9 → 48,12 |
#define TASKMAP_MAX_RECORDS 32 |
#define MEMMAP_MAX_RECORDS 32 |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
typedef struct { |
void * addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
/branches/dynload/kernel/arch/sparc64/src/console.c |
---|
56,7 → 56,7 |
#include <genarch/ofw/ofw_tree.h> |
#include <arch.h> |
#include <panic.h> |
#include <func.h> |
#include <string.h> |
#include <print.h> |
#define KEYBOARD_POLL_PAUSE 50000 /* 50ms */ |
/branches/dynload/kernel/arch/sparc64/src/sparc64.c |
---|
47,10 → 47,11 |
#include <genarch/ofw/ofw_tree.h> |
#include <userspace.h> |
#include <ddi/irq.h> |
#include <string.h> |
bootinfo_t bootinfo; |
/** Perform sparc64 specific initialization before main_bsp() is called. */ |
/** Perform sparc64-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
/* Copy init task info. */ |
61,6 → 62,8 |
for (i = 0; i < bootinfo.taskmap.count; i++) { |
init.tasks[i].addr = (uintptr_t) bootinfo.taskmap.tasks[i].addr; |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
strncpy(init.tasks[i].name, bootinfo.taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
/* Copy boot allocations info. */ |
/branches/dynload/kernel/arch/sparc64/src/drivers/kbd.c |
---|
45,7 → 45,7 |
#include <arch/mm/page.h> |
#include <arch/types.h> |
#include <align.h> |
#include <func.h> |
#include <string.h> |
#include <print.h> |
#include <sysinfo/sysinfo.h> |
169,7 → 169,7 |
sysinfo_set_item_val("kbd.type", NULL, KBD_Z8530); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.virtual", NULL, |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) z8530); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
break; |
189,7 → 189,7 |
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.virtual", NULL, |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) ns16550); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
break; |
/branches/dynload/kernel/arch/sparc64/src/drivers/scr.c |
---|
37,7 → 37,7 |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <arch/types.h> |
#include <func.h> |
#include <string.h> |
#include <align.h> |
#include <print.h> |
/branches/dynload/kernel/arch/sparc64/src/drivers/sgcn.c |
---|
38,7 → 38,7 |
#include <arch/drivers/kbd.h> |
#include <genarch/ofw/ofw_tree.h> |
#include <debug.h> |
#include <func.h> |
#include <string.h> |
#include <print.h> |
#include <mm/page.h> |
#include <ipc/irq.h> |
/branches/dynload/kernel/arch/sparc64/src/drivers/pci.c |
---|
42,7 → 42,7 |
#include <arch/types.h> |
#include <debug.h> |
#include <print.h> |
#include <func.h> |
#include <string.h> |
#include <arch/asm.h> |
#include <sysinfo/sysinfo.h> |
/branches/dynload/kernel/arch/ia64/include/types.h |
---|
65,10 → 65,6 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
typedef struct { |
unative_t fnc; |
unative_t gp; |
/branches/dynload/kernel/arch/ia64/include/bootinfo.h |
---|
39,10 → 39,13 |
#define EFI_MEMMAP_IO 1 |
#define EFI_MEMMAP_IO_PORTS 2 |
/** Size of buffer for storing task name in binit_task_t. */ |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
typedef struct { |
void *addr; |
unsigned long size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} binit_task_t; |
typedef struct { |
/branches/dynload/kernel/arch/ia64/include/asm.h |
---|
36,6 → 36,7 |
#define KERN_ia64_ASM_H_ |
#include <config.h> |
#include <typedefs.h> |
#include <arch/types.h> |
#include <arch/register.h> |
88,7 → 89,7 |
asm volatile ("mf\n" ::: "memory"); |
return *((uint16_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xffE) | ((prt >> 2) << 12)))); |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
/branches/dynload/kernel/arch/ia64/src/ia64.c |
---|
62,6 → 62,7 |
#include <panic.h> |
#include <print.h> |
#include <sysinfo/sysinfo.h> |
#include <string.h> |
/* NS16550 as a COM 1 */ |
#define NS16550_IRQ (4 + LEGACY_INTERRUPT_BASE) |
70,6 → 71,7 |
static uint64_t iosapic_base = 0xfec00000; |
/** Performs ia64-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
/* Setup usermode init tasks. */ |
83,6 → 85,8 |
((unsigned long) bootinfo->taskmap.tasks[i].addr) | |
VRN_MASK; |
init.tasks[i].size = bootinfo->taskmap.tasks[i].size; |
strncpy(init.tasks[i].name, bootinfo->taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
} |
167,11 → 171,18 |
inr = NS16550_IRQ; |
(void) ns16550_init((ns16550_t *)NS16550_BASE, devno, inr, NULL, NULL); |
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550); |
sysinfo_set_item_val("kbd.port", NULL, (uintptr_t)NS16550_BASE); |
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); |
sysinfo_set_item_val("kbd.type", NULL, KBD_LEGACY); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
#endif |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
/branches/dynload/kernel/arch/arm32/include/regutils.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** |
57,7 → 57,10 |
static inline uint32_t nm## _status_reg_read(void) \ |
{ \ |
uint32_t retval; \ |
asm volatile("mrs %0, " #reg : "=r" (retval)); \ |
asm volatile( \ |
"mrs %[retval], " #reg \ |
: [retval] "=r" (retval) \ |
); \ |
return retval; \ |
} |
64,7 → 67,10 |
#define GEN_STATUS_WRITE(nm,reg,fieldname, field) \ |
static inline void nm## _status_reg_ ##fieldname## _write(uint32_t value) \ |
{ \ |
asm volatile("msr " #reg "_" #field ", %0" : : "r" (value)); \ |
asm volatile( \ |
"msr " #reg "_" #field ", %[value]" \ |
:: [value] "r" (value) \ |
); \ |
} |
/branches/dynload/kernel/arch/arm32/include/types.h |
---|
64,10 → 64,6 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
typedef struct { |
} fncptr_t; |
/branches/dynload/kernel/arch/arm32/include/atomic.h |
---|
26,10 → 26,10 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
/** @file |
* @brief Atomic operations. |
*/ |
42,26 → 42,26 |
* @param i Value to be added. |
* |
* @return Value after addition. |
* |
*/ |
static inline long atomic_add(atomic_t *val, int i) |
{ |
int ret; |
volatile long *mem = &(val->count); |
asm volatile ( |
"1:\n" |
"ldr r2, [%1] \n" |
"add r3, r2, %2 \n" |
"str r3, %0 \n" |
"swp r3, r3, [%1] \n" |
"cmp r3, r2 \n" |
"bne 1b \n" |
: "=m" (ret) |
: "r" (mem), "r" (i) |
"1:\n" |
"ldr r2, [%[mem]]\n" |
"add r3, r2, %[i]\n" |
"str r3, %[ret]\n" |
"swp r3, r3, [%[mem]]\n" |
"cmp r3, r2\n" |
"bne 1b\n" |
: [ret] "=m" (ret) |
: [mem] "r" (mem), [i] "r" (i) |
: "r3", "r2" |
); |
return ret; |
} |
/branches/dynload/kernel/arch/arm32/include/arch.h |
---|
39,11 → 39,14 |
#define TASKMAP_MAX_RECORDS 32 |
#define CPUMAP_MAX_RECORDS 32 |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
#include <typedefs.h> |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
/branches/dynload/kernel/arch/arm32/include/asm.h |
---|
26,10 → 26,10 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
/** @file |
* @brief Declarations of functions implemented in assembly. |
*/ |
36,6 → 36,7 |
#ifndef KERN_arm32_ASM_H_ |
#define KERN_arm32_ASM_H_ |
#include <typedefs.h> |
#include <arch/types.h> |
#include <arch/stack.h> |
#include <config.h> |
77,18 → 78,19 |
} |
/** Return base address of current stack. |
* |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
* |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
asm volatile ( |
"and %0, sp, %1\n" |
: "=r" (v) |
: "r" (~(STACK_SIZE - 1)) |
"and %[v], sp, %[size]\n" |
: [v] "=r" (v) |
: [size] "r" (~(STACK_SIZE - 1)) |
); |
return v; |
} |
/branches/dynload/kernel/arch/arm32/include/mm/page.h |
---|
193,9 → 193,8 |
static inline void set_ptl0_addr(pte_level0_t *pt) |
{ |
asm volatile ( |
"mcr p15, 0, %0, c2, c0, 0 \n" |
: |
: "r"(pt) |
"mcr p15, 0, %[pt], c2, c0, 0\n" |
:: [pt] "r" (pt) |
); |
} |
/branches/dynload/kernel/arch/arm32/include/barrier.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
39,12 → 39,12 |
/* |
* TODO: implement true ARM memory barriers for macros below. |
*/ |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define memory_barrier() asm volatile ("" ::: "memory") |
#define read_barrier() asm volatile ("" ::: "memory") |
#define write_barrier() asm volatile ("" ::: "memory") |
#define memory_barrier() asm volatile ("" ::: "memory") |
#define read_barrier() asm volatile ("" ::: "memory") |
#define write_barrier() asm volatile ("" ::: "memory") |
#define smc_coherence(a) |
#define smc_coherence_block(a, l) |
/branches/dynload/kernel/arch/arm32/src/exception.c |
---|
63,57 → 63,60 |
* |
* Temporary exception stack is used to save a few registers |
* before stack switch takes place. |
* |
*/ |
inline static void setup_stack_and_save_regs() |
{ |
asm volatile( |
"ldr r13, =exc_stack \n" |
"stmfd r13!, {r0} \n" |
"mrs r0, spsr \n" |
"and r0, r0, #0x1f \n" |
"cmp r0, #0x10 \n" |
"bne 1f \n" |
asm volatile ( |
"ldr r13, =exc_stack\n" |
"stmfd r13!, {r0}\n" |
"mrs r0, spsr\n" |
"and r0, r0, #0x1f\n" |
"cmp r0, #0x10\n" |
"bne 1f\n" |
/* prev mode was usermode */ |
"ldmfd r13!, {r0} \n" |
"ldr r13, =supervisor_sp \n" |
"ldr r13, [r13] \n" |
"stmfd r13!, {lr} \n" |
"stmfd r13!, {r0-r12} \n" |
"stmfd r13!, {r13, lr}^ \n" |
"mrs r0, spsr \n" |
"stmfd r13!, {r0} \n" |
"b 2f \n" |
"ldmfd r13!, {r0}\n" |
"ldr r13, =supervisor_sp\n" |
"ldr r13, [r13]\n" |
"stmfd r13!, {lr}\n" |
"stmfd r13!, {r0-r12}\n" |
"stmfd r13!, {r13, lr}^\n" |
"mrs r0, spsr\n" |
"stmfd r13!, {r0}\n" |
"b 2f\n" |
/* mode was not usermode */ |
"1:\n" |
"stmfd r13!, {r1, r2, r3} \n" |
"mrs r1, cpsr \n" |
"mov r2, lr \n" |
"bic r1, r1, #0x1f \n" |
"orr r1, r1, r0 \n" |
"mrs r0, cpsr \n" |
"msr cpsr_c, r1 \n" |
"mov r3, r13 \n" |
"stmfd r13!, {r2} \n" |
"mov r2, lr \n" |
"stmfd r13!, {r4-r12} \n" |
"mov r1, r13 \n" |
/* the following two lines are for debugging */ |
"mov sp, #0 \n" |
"mov lr, #0 \n" |
"msr cpsr_c, r0 \n" |
"ldmfd r13!, {r4, r5, r6, r7} \n" |
"stmfd r1!, {r4, r5, r6} \n" |
"stmfd r1!, {r7} \n" |
"stmfd r1!, {r2} \n" |
"stmfd r1!, {r3} \n" |
"mrs r0, spsr \n" |
"stmfd r1!, {r0} \n" |
"mov r13, r1 \n" |
"2:\n" |
"1:\n" |
"stmfd r13!, {r1, r2, r3}\n" |
"mrs r1, cpsr\n" |
"mov r2, lr\n" |
"bic r1, r1, #0x1f\n" |
"orr r1, r1, r0\n" |
"mrs r0, cpsr\n" |
"msr cpsr_c, r1\n" |
"mov r3, r13\n" |
"stmfd r13!, {r2}\n" |
"mov r2, lr\n" |
"stmfd r13!, {r4-r12}\n" |
"mov r1, r13\n" |
/* the following two lines are for debugging */ |
"mov sp, #0\n" |
"mov lr, #0\n" |
"msr cpsr_c, r0\n" |
"ldmfd r13!, {r4, r5, r6, r7}\n" |
"stmfd r1!, {r4, r5, r6}\n" |
"stmfd r1!, {r7}\n" |
"stmfd r1!, {r2}\n" |
"stmfd r1!, {r3}\n" |
"mrs r0, spsr\n" |
"stmfd r1!, {r0}\n" |
"mov r13, r1\n" |
"2:\n" |
); |
} |
189,10 → 192,13 |
} |
/** Calls exception dispatch routine. */ |
#define CALL_EXC_DISPATCH(exception) \ |
asm("mov r0, %0" : : "i" (exception)); \ |
asm("mov r1, r13"); \ |
asm("bl exc_dispatch"); |
#define CALL_EXC_DISPATCH(exception) \ |
asm volatile ( \ |
"mov r0, %[exc]\n" \ |
"mov r1, r13\n" \ |
"bl exc_dispatch\n" \ |
:: [exc] "i" (exception) \ |
);\ |
/** General exception handler. |
* |
201,9 → 207,9 |
* |
* @param exception Exception number. |
*/ |
#define PROCESS_EXCEPTION(exception) \ |
setup_stack_and_save_regs(); \ |
CALL_EXC_DISPATCH(exception) \ |
#define PROCESS_EXCEPTION(exception) \ |
setup_stack_and_save_regs(); \ |
CALL_EXC_DISPATCH(exception) \ |
load_regs(); |
/** Updates specified exception vector to jump to given handler. |
333,17 → 339,23 |
{ |
uint32_t control_reg; |
asm volatile("mrc p15, 0, %0, c1, c1" : "=r" (control_reg)); |
asm volatile ( |
"mrc p15, 0, %[control_reg], c1, c1" |
: [control_reg] "=r" (control_reg) |
); |
/* switch on the high vectors bit */ |
control_reg |= CP15_R1_HIGH_VECTORS_BIT; |
asm volatile("mcr p15, 0, %0, c1, c1" : : "r" (control_reg)); |
asm volatile ( |
"mcr p15, 0, %[control_reg], c1, c1" |
:: [control_reg] "r" (control_reg) |
); |
} |
#endif |
/** Initializes exception handling. |
* |
* |
* Installs low-level exception handlers and then registers |
* exceptions and their handlers to kernel exception dispatcher. |
*/ |
/branches/dynload/kernel/arch/arm32/src/arm32.c |
---|
48,8 → 48,9 |
#include <arch/machine.h> |
#include <userspace.h> |
#include <macros.h> |
#include <string.h> |
/** Performs arm32 specific initialization before main_bsp() is called. */ |
/** Performs arm32-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo) |
{ |
unsigned int i; |
59,6 → 60,8 |
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); ++i) { |
init.tasks[i].addr = bootinfo->tasks[i].addr; |
init.tasks[i].size = bootinfo->tasks[i].size; |
strncpy(init.tasks[i].name, bootinfo->tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
} |
/branches/dynload/kernel/arch/arm32/src/cpu/cpu.c |
---|
36,7 → 36,7 |
#include <arch/cpu.h> |
#include <cpu.h> |
#include <arch.h> |
#include <print.h> |
#include <print.h> |
/** Number of indexes left out in the #imp_data array */ |
#define IMP_DATA_START_OFFSET 0x40 |
82,10 → 82,10 |
{ |
uint32_t ident; |
asm volatile ( |
"mrc p15, 0, %0, c0, c0, 0\n" |
: "=r" (ident) |
"mrc p15, 0, %[ident], c0, c0, 0\n" |
: [ident] "=r" (ident) |
); |
cpu->imp_num = ident >> 24; |
cpu->variant_num = (ident << 8) >> 28; |
cpu->arch_num = (ident << 12) >> 28; |
/branches/dynload/kernel/arch/arm32/src/mm/tlb.c |
---|
48,7 → 48,7 |
asm volatile ( |
"eor r1, r1\n" |
"mcr p15, 0, r1, c8, c7, 0\n" |
: : : "r1" |
::: "r1" |
); |
} |
68,9 → 68,8 |
static inline void invalidate_page(uintptr_t page) |
{ |
asm volatile ( |
"mcr p15, 0, %0, c8, c7, 1" |
: |
: "r" (page) |
"mcr p15, 0, %[page], c8, c7, 1\n" |
:: [page] "r" (page) |
); |
} |
/branches/dynload/kernel/arch/arm32/src/mm/page_fault.c |
---|
49,12 → 49,13 |
static inline fault_status_t read_fault_status_register(void) |
{ |
fault_status_union_t fsu; |
/* fault status is stored in CP15 register 5 */ |
asm volatile ( |
"mrc p15, 0, %0, c5, c0, 0" |
: "=r"(fsu.dummy) |
"mrc p15, 0, %[dummy], c5, c0, 0" |
: [dummy] "=r" (fsu.dummy) |
); |
return fsu.fs; |
} |
61,17 → 62,18 |
/** Returns FAR (fault address register) content. |
* |
* @return FAR (fault address register) content (address that caused a page |
* fault) |
* fault) |
*/ |
static inline uintptr_t read_fault_address_register(void) |
{ |
uintptr_t ret; |
/* fault adress is stored in CP15 register 6 */ |
asm volatile ( |
"mrc p15, 0, %0, c6, c0, 0" |
: "=r"(ret) |
"mrc p15, 0, %[ret], c6, c0, 0" |
: [ret] "=r" (ret) |
); |
return ret; |
} |
80,29 → 82,26 |
* @param instr Instruction |
* |
* @return true when instruction is load/store, false otherwise |
* |
*/ |
static inline bool is_load_store_instruction(instruction_t instr) |
{ |
/* load store immediate offset */ |
if (instr.type == 0x2) { |
if (instr.type == 0x2) |
return true; |
} |
/* load store register offset */ |
if (instr.type == 0x3 && instr.bit4 == 0) { |
if ((instr.type == 0x3) && (instr.bit4 == 0)) |
return true; |
} |
/* load store multiple */ |
if (instr.type == 0x4) { |
if (instr.type == 0x4) |
return true; |
} |
/* oprocessor load/store */ |
if (instr.type == 0x6) { |
if (instr.type == 0x6) |
return true; |
} |
return false; |
} |
115,12 → 114,11 |
static inline bool is_swap_instruction(instruction_t instr) |
{ |
/* swap, swapb instruction */ |
if (instr.type == 0x0 && |
(instr.opcode == 0x8 || instr.opcode == 0xa) && |
instr.access == 0x0 && instr.bits567 == 0x4 && instr.bit4 == 1) { |
if ((instr.type == 0x0) && |
((instr.opcode == 0x8) || (instr.opcode == 0xa)) && |
(instr.access == 0x0) && (instr.bits567 == 0x4) && (instr.bit4 == 1)) |
return true; |
} |
return false; |
} |
/branches/dynload/kernel/arch/arm32/src/userspace.c |
---|
90,12 → 90,11 |
/* set user mode, set registers, jump */ |
asm volatile ( |
"mov sp, %0 \n" |
"msr spsr_c, %1 \n" |
"ldmfd sp!, {r0-r12, sp, lr}^ \n" |
"mov sp, %[ustate]\n" |
"msr spsr_c, %[user_mode]\n" |
"ldmfd sp!, {r0-r12, sp, lr}^\n" |
"ldmfd sp!, {pc}^\n" |
: |
: "r" (&ustate), "r" (user_mode) |
:: [ustate] "r" (&ustate), [user_mode] "r" (user_mode) |
); |
/* unreachable */ |
/branches/dynload/kernel/arch/ppc32/include/types.h |
---|
57,10 → 57,6 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
typedef struct { |
} fncptr_t; |
/branches/dynload/kernel/arch/ppc32/include/boot/boot.h |
---|
45,11 → 45,14 |
#ifndef __ASM__ |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
#include <arch/types.h> |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
/branches/dynload/kernel/arch/ppc32/include/asm.h |
---|
36,6 → 36,7 |
#define KERN_ppc32_ASM_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <config.h> |
/** Enable interrupts. |
/branches/dynload/kernel/arch/ppc32/src/ppc32.c |
---|
46,11 → 46,13 |
#include <ddi/irq.h> |
#include <arch/drivers/pic.h> |
#include <macros.h> |
#include <string.h> |
#define IRQ_COUNT 64 |
bootinfo_t bootinfo; |
/** Performs ppc32-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
init.cnt = bootinfo.taskmap.count; |
60,6 → 62,8 |
for (i = 0; i < min3(bootinfo.taskmap.count, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) { |
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr); |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
strncpy(init.tasks[i].name, bootinfo.taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
} |
/branches/dynload/kernel/arch/amd64/include/types.h |
---|
57,10 → 57,6 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
typedef struct { |
} fncptr_t; |
/branches/dynload/kernel/arch/amd64/include/atomic.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
41,17 → 41,29 |
static inline void atomic_inc(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ("lock incq %0\n" : "+m" (val->count)); |
asm volatile ( |
"lock incq %[count]\n" |
: [count] "+m" (val->count) |
); |
#else |
asm volatile ("incq %0\n" : "+m" (val->count)); |
asm volatile ( |
"incq %[count]\n" |
: [count] "+m" (val->count) |
); |
#endif /* CONFIG_SMP */ |
} |
static inline void atomic_dec(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ("lock decq %0\n" : "+m" (val->count)); |
asm volatile ( |
"lock decq %[count]\n" |
: [count] "+m" (val->count) |
); |
#else |
asm volatile ("decq %0\n" : "+m" (val->count)); |
asm volatile ( |
"decq %[count]\n" |
: [count] "+m" (val->count) |
); |
#endif /* CONFIG_SMP */ |
} |
58,12 → 70,12 |
static inline long atomic_postinc(atomic_t *val) |
{ |
long r = 1; |
asm volatile ( |
"lock xaddq %1, %0\n" |
: "+m" (val->count), "+r" (r) |
"lock xaddq %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r" (r) |
); |
return r; |
} |
72,23 → 84,23 |
long r = -1; |
asm volatile ( |
"lock xaddq %1, %0\n" |
: "+m" (val->count), "+r" (r) |
"lock xaddq %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r" (r) |
); |
return r; |
} |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
static inline uint64_t test_and_set(atomic_t *val) { |
uint64_t v; |
asm volatile ( |
"movq $1, %0\n" |
"xchgq %0, %1\n" |
: "=r" (v), "+m" (val->count) |
"movq $1, %[v]\n" |
"xchgq %[v], %[count]\n" |
: [v] "=r" (v), [count] "+m" (val->count) |
); |
return v; |
99,7 → 111,7 |
static inline void atomic_lock_arch(atomic_t *val) |
{ |
uint64_t tmp; |
preemption_disable(); |
asm volatile ( |
"0:\n" |
106,15 → 118,15 |
#ifdef CONFIG_HT |
"pause\n" |
#endif |
"mov %0, %1\n" |
"testq %1, %1\n" |
"mov %[count], %[tmp]\n" |
"testq %[tmp], %[tmp]\n" |
"jnz 0b\n" /* lightweight looping on locked spinlock */ |
"incq %1\n" /* now use the atomic operation */ |
"xchgq %0, %1\n" |
"testq %1, %1\n" |
"incq %[tmp]\n" /* now use the atomic operation */ |
"xchgq %[count], %[tmp]\n" |
"testq %[tmp], %[tmp]\n" |
"jnz 0b\n" |
: "+m" (val->count), "=&r" (tmp) |
: [count] "+m" (val->count), [tmp] "=&r" (tmp) |
); |
/* |
* Prevent critical section code from bleeding out this way up. |
/branches/dynload/kernel/arch/amd64/include/boot/boot.h |
---|
42,8 → 42,17 |
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 |
#define MULTIBOOT_HEADER_FLAGS 0x00010003 |
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002 |
#ifndef __ASM__ |
#ifdef CONFIG_SMP |
/* This is only a symbol so the type is dummy. Obtain the value using &. */ |
extern int _hardcoded_unmapped_size; |
#endif /* CONFIG_SMP */ |
#endif /* __ASM__ */ |
#endif |
/** @} |
/branches/dynload/kernel/arch/amd64/include/arch.h |
---|
35,6 → 35,10 |
#ifndef KERN_amd64_ARCH_H_ |
#define KERN_amd64_ARCH_H_ |
#include <genarch/multiboot/multiboot.h> |
extern void arch_pre_main(uint32_t, const multiboot_info_t *); |
#endif |
/** @} |
/branches/dynload/kernel/arch/amd64/include/asm.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
36,6 → 36,8 |
#define KERN_amd64_ASM_H_ |
#include <config.h> |
#include <arch/types.h> |
#include <typedefs.h> |
extern void asm_delay_loop(uint32_t t); |
extern void asm_fake_loop(uint32_t t); |
45,12 → 47,17 |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
* |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
asm volatile ("andq %%rsp, %0\n" : "=r" (v) : "0" (~((uint64_t)STACK_SIZE-1))); |
asm volatile ( |
"andq %%rsp, %[v]\n" |
: [v] "=r" (v) |
: "0" (~((uint64_t) STACK_SIZE-1)) |
); |
return v; |
} |
72,12 → 79,18 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
uint8_t val; |
asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port)); |
asm volatile ( |
"inb %w[port], %b[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
} |
87,12 → 100,18 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
uint16_t val; |
asm volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port)); |
asm volatile ( |
"inw %w[port], %w[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
} |
102,12 → 121,18 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
uint32_t val; |
asm volatile ("inl %w1, %0 \n" : "=a" (val) : "d" (port)); |
asm volatile ( |
"inl %w[port], %[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
} |
117,10 → 142,14 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_8(ioport8_t *port, uint8_t val) |
{ |
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port)); |
asm volatile ( |
"outb %b[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
/** Word to port |
129,10 → 158,14 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_16(ioport16_t *port, uint16_t val) |
{ |
asm volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port)); |
asm volatile ( |
"outw %w[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
/** Double word to port |
141,10 → 174,14 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_32(ioport32_t *port, uint32_t val) |
{ |
asm volatile ("outl %0, %w1\n" : : "a" (val), "d" (port)); |
asm volatile ( |
"outl %[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
/** Swap Hidden part of GS register with visible one */ |
159,15 → 196,18 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_enable(void) { |
ipl_t v; |
__asm__ volatile ( |
asm volatile ( |
"pushfq\n" |
"popq %0\n" |
"popq %[v]\n" |
"sti\n" |
: "=r" (v) |
: [v] "=r" (v) |
); |
return v; |
} |
177,15 → 217,18 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_disable(void) { |
ipl_t v; |
__asm__ volatile ( |
asm volatile ( |
"pushfq\n" |
"popq %0\n" |
"popq %[v]\n" |
"cli\n" |
: "=r" (v) |
); |
: [v] "=r" (v) |
); |
return v; |
} |
194,13 → 237,14 |
* Restore EFLAGS. |
* |
* @param ipl Saved interrupt priority level. |
* |
*/ |
static inline void interrupts_restore(ipl_t ipl) { |
__asm__ volatile ( |
"pushq %0\n" |
asm volatile ( |
"pushq %[ipl]\n" |
"popfq\n" |
: : "r" (ipl) |
); |
:: [ipl] "r" (ipl) |
); |
} |
/** Return interrupt priority level. |
208,14 → 252,17 |
* Return EFLAFS. |
* |
* @return Current interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_read(void) { |
ipl_t v; |
__asm__ volatile ( |
asm volatile ( |
"pushfq\n" |
"popq %0\n" |
: "=r" (v) |
"popq %[v]\n" |
: [v] "=r" (v) |
); |
return v; |
} |
222,21 → 269,25 |
/** Write to MSR */ |
static inline void write_msr(uint32_t msr, uint64_t value) |
{ |
__asm__ volatile ( |
"wrmsr;" : : "c" (msr), |
"a" ((uint32_t)(value)), |
"d" ((uint32_t)(value >> 32)) |
); |
asm volatile ( |
"wrmsr\n" |
:: "c" (msr), |
"a" ((uint32_t) (value)), |
"d" ((uint32_t) (value >> 32)) |
); |
} |
static inline unative_t read_msr(uint32_t msr) |
{ |
uint32_t ax, dx; |
__asm__ volatile ( |
"rdmsr;" : "=a"(ax), "=d"(dx) : "c" (msr) |
); |
return ((uint64_t)dx << 32) | ax; |
asm volatile ( |
"rdmsr\n" |
: "=a" (ax), "=d" (dx) |
: "c" (msr) |
); |
return ((uint64_t) dx << 32) | ax; |
} |
243,29 → 294,29 |
/** Enable local APIC |
* |
* Enable local APIC in MSR. |
* |
*/ |
static inline void enable_l_apic_in_msr() |
{ |
__asm__ volatile ( |
asm volatile ( |
"movl $0x1b, %%ecx\n" |
"rdmsr\n" |
"orl $(1<<11),%%eax\n" |
"orl $(1 << 11),%%eax\n" |
"orl $(0xfee00000),%%eax\n" |
"wrmsr\n" |
: |
: |
:"%eax","%ecx","%edx" |
); |
::: "%eax","%ecx","%edx" |
); |
} |
static inline uintptr_t * get_ip() |
{ |
uintptr_t *ip; |
__asm__ volatile ( |
"mov %%rip, %0" |
: "=r" (ip) |
); |
asm volatile ( |
"mov %%rip, %[ip]" |
: [ip] "=r" (ip) |
); |
return ip; |
} |
272,59 → 323,84 |
/** Invalidate TLB Entry. |
* |
* @param addr Address on a page whose TLB entry is to be invalidated. |
* |
*/ |
static inline void invlpg(uintptr_t addr) |
{ |
__asm__ volatile ("invlpg %0\n" :: "m" (*((unative_t *)addr))); |
asm volatile ( |
"invlpg %[addr]\n" |
:: [addr] "m" (*((unative_t *) addr)) |
); |
} |
/** Load GDTR register from memory. |
* |
* @param gdtr_reg Address of memory from where to load GDTR. |
* |
*/ |
static inline void gdtr_load(struct ptr_16_64 *gdtr_reg) |
{ |
__asm__ volatile ("lgdtq %0\n" : : "m" (*gdtr_reg)); |
asm volatile ( |
"lgdtq %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
} |
/** Store GDTR register to memory. |
* |
* @param gdtr_reg Address of memory to where to load GDTR. |
* |
*/ |
static inline void gdtr_store(struct ptr_16_64 *gdtr_reg) |
{ |
__asm__ volatile ("sgdtq %0\n" : : "m" (*gdtr_reg)); |
asm volatile ( |
"sgdtq %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
} |
/** Load IDTR register from memory. |
* |
* @param idtr_reg Address of memory from where to load IDTR. |
* |
*/ |
static inline void idtr_load(struct ptr_16_64 *idtr_reg) |
{ |
__asm__ volatile ("lidtq %0\n" : : "m" (*idtr_reg)); |
asm volatile ( |
"lidtq %[idtr_reg]\n" |
:: [idtr_reg] "m" (*idtr_reg)); |
} |
/** Load TR from descriptor table. |
* |
* @param sel Selector specifying descriptor of TSS segment. |
* |
*/ |
static inline void tr_load(uint16_t sel) |
{ |
__asm__ volatile ("ltr %0" : : "r" (sel)); |
asm volatile ( |
"ltr %[sel]" |
:: [sel] "r" (sel) |
); |
} |
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ |
{ \ |
unative_t res; \ |
__asm__ volatile ("movq %%" #reg ", %0" : "=r" (res) ); \ |
return res; \ |
} |
{ \ |
unative_t res; \ |
asm volatile ( \ |
"movq %%" #reg ", %[res]" \ |
: [res] "=r" (res) \ |
); \ |
return res; \ |
} |
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \ |
{ \ |
__asm__ volatile ("movq %0, %%" #reg : : "r" (regn)); \ |
} |
{ \ |
asm volatile ( \ |
"movq %[regn], %%" #reg \ |
:: [regn] "r" (regn) \ |
); \ |
} |
GEN_READ_REG(cr0) |
GEN_READ_REG(cr2) |
/branches/dynload/kernel/arch/amd64/src/fpu_context.c |
---|
39,9 → 39,9 |
void fpu_context_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxsave %0" |
: "=m"(*fctx) |
); |
"fxsave %[fctx]\n" |
: [fctx] "=m" (*fctx) |
); |
} |
/** Restore FPU (mmx,sse) context using fxrstor instruction */ |
48,9 → 48,9 |
void fpu_context_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxrstor %0" |
: "=m"(*fctx) |
); |
"fxrstor %[fctx]\n" |
: [fctx] "=m" (*fctx) |
); |
} |
void fpu_init() |
57,7 → 57,7 |
{ |
/* TODO: Zero all SSE, MMX etc. registers */ |
asm volatile ( |
"fninit;" |
"fninit\n" |
); |
} |
/branches/dynload/kernel/arch/amd64/src/cpu/cpu.c |
---|
77,21 → 77,19 |
void cpu_setup_fpu(void) |
{ |
asm volatile ( |
"movq %%cr0, %%rax;" |
"btsq $1, %%rax;" /* cr0.mp */ |
"btrq $2, %%rax;" /* cr0.em */ |
"movq %%rax, %%cr0;" |
"movq %%cr4, %%rax;" |
"bts $9, %%rax;" /* cr4.osfxsr */ |
"movq %%rax, %%cr4;" |
: |
: |
:"%rax" |
); |
"movq %%cr0, %%rax\n" |
"btsq $1, %%rax\n" /* cr0.mp */ |
"btrq $2, %%rax\n" /* cr0.em */ |
"movq %%rax, %%cr0\n" |
"movq %%cr4, %%rax\n" |
"bts $9, %%rax\n" /* cr4.osfxsr */ |
"movq %%rax, %%cr4\n" |
::: "%rax" |
); |
} |
/** Set the TS flag to 1. |
/** Set the TS flag to 1. |
* |
* If a thread accesses coprocessor, exception is run, which |
* does a lazy fpu context switch. |
99,26 → 97,22 |
*/ |
void fpu_disable(void) |
{ |
asm volatile ( |
"mov %%cr0,%%rax;" |
"bts $3,%%rax;" |
"mov %%rax,%%cr0;" |
: |
: |
:"%rax" |
); |
asm volatile ( |
"mov %%cr0, %%rax\n" |
"bts $3, %%rax\n" |
"mov %%rax, %%cr0\n" |
::: "%rax" |
); |
} |
void fpu_enable(void) |
{ |
asm volatile ( |
"mov %%cr0,%%rax;" |
"btr $3,%%rax;" |
"mov %%rax,%%cr0;" |
: |
: |
:"%rax" |
); |
asm volatile ( |
"mov %%cr0, %%rax\n" |
"btr $3, %%rax\n" |
"mov %%rax, %%cr0\n" |
::: "%rax" |
); |
} |
void cpu_arch_init(void) |
/branches/dynload/kernel/arch/amd64/src/amd64.c |
---|
39,6 → 39,7 |
#include <config.h> |
#include <proc/thread.h> |
#include <genarch/multiboot/multiboot.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <genarch/drivers/ega/ega.h> |
#include <arch/drivers/vesa.h> |
45,6 → 46,7 |
#include <genarch/kbd/i8042.h> |
#include <arch/drivers/i8254.h> |
#include <arch/drivers/i8259.h> |
#include <arch/boot/boot.h> |
#ifdef CONFIG_SMP |
#include <arch/smp/apic.h> |
65,7 → 67,6 |
#include <ddi/device.h> |
#include <sysinfo/sysinfo.h> |
/** Disable I/O on non-privileged levels |
* |
* Clean IOPL(12,13) and NT(14) flags in EFLAGS register |
72,15 → 73,13 |
*/ |
static void clean_IOPL_NT_flags(void) |
{ |
asm ( |
asm volatile ( |
"pushfq\n" |
"pop %%rax\n" |
"and $~(0x7000), %%rax\n" |
"pushq %%rax\n" |
"popfq\n" |
: |
: |
: "%rax" |
::: "%rax" |
); |
} |
90,16 → 89,31 |
*/ |
static void clean_AM_flag(void) |
{ |
asm ( |
asm volatile ( |
"mov %%cr0, %%rax\n" |
"and $~(0x40000), %%rax\n" |
"mov %%rax, %%cr0\n" |
: |
: |
: "%rax" |
::: "%rax" |
); |
} |
/** Perform amd64-specific initialization before main_bsp() is called. |
* |
* @param signature Should contain the multiboot signature. |
* @param mi Pointer to the multiboot information structure. |
*/ |
void arch_pre_main(uint32_t signature, const multiboot_info_t *mi) |
{ |
/* Parse multiboot information obtained from the bootloader. */ |
multiboot_info_parse(signature, mi); |
#ifdef CONFIG_SMP |
/* Copy AP bootstrap routines below 1 MB. */ |
memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET, |
(size_t) &_hardcoded_unmapped_size); |
#endif |
} |
void arch_pre_mm_init(void) |
{ |
/* Enable no-execute pages */ |
185,6 → 199,10 |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
} |
void calibrate_delay_loop(void) |
/branches/dynload/kernel/arch/amd64/src/boot/boot.S |
---|
175,119 → 175,18 |
.code64 |
start64: |
movq $(PA2KA(START_STACK)), %rsp |
movl grub_eax, %eax |
movl grub_ebx, %ebx |
# 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. |
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature |
je valid_boot |
xorl %ecx, %ecx # no memory size or map available |
movl %ecx, e820counter |
jmp invalid_boot |
valid_boot: |
movl (%ebx), %eax # ebx = physical address of struct multiboot_info |
bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid) |
jc mods_valid |
xorq %rcx, %rcx |
movq %rcx, init |
jmp mods_end |
mods_valid: |
xorq %rcx, %rcx |
movl 20(%ebx), %ecx # mbi->mods_count |
movq %rcx, init |
cmpl $0, %ecx |
je mods_end |
movl 24(%ebx), %esi # mbi->mods_addr |
movq $init, %rdi |
mods_loop: |
xorq %rdx, %rdx |
movl 0(%esi), %edx # mods->mod_start |
movq $0xffff800000000000, %r10 |
addq %r10, %rdx |
movq %rdx, 8(%rdi) |
xorq %rdx, %rdx |
movl 4(%esi), %edx |
subl 0(%esi), %edx # mods->mod_end - mods->mod_start |
movq %rdx, 16(%rdi) |
addl $16, %esi |
addq $48, %rdi |
loop mods_loop |
mods_end: |
bt $6, %eax # mbi->flags[6] (mmap_length, mmap_addr valid) |
jc mmap_valid |
xorl %edx, %edx |
jmp mmap_invalid |
mmap_valid: |
movl 44(%ebx), %ecx # mbi->mmap_length |
movl 48(%ebx), %esi # mbi->mmap_addr |
movq $e820table, %rdi |
xorl %edx, %edx |
mmap_loop: |
cmpl $0, %ecx |
jle mmap_end |
movl 4(%esi), %eax # mmap->base_addr_low |
movl %eax, (%rdi) |
movl 8(%esi), %eax # mmap->base_addr_high |
movl %eax, 4(%rdi) |
movl 12(%esi), %eax # mmap->length_low |
movl %eax, 8(%rdi) |
movl 16(%esi), %eax # mmap->length_high |
movl %eax, 12(%rdi) |
movl 20(%esi), %eax # mmap->type |
movl %eax, 16(%rdi) |
movl (%esi), %eax # mmap->size |
addl $0x4, %eax |
addl %eax, %esi |
subl %eax, %ecx |
addq $MEMMAP_E820_RECORD_SIZE, %rdi |
incl %edx |
jmp mmap_loop |
mmap_end: |
mmap_invalid: |
movl %edx, e820counter |
invalid_boot: |
#ifdef CONFIG_SMP |
# copy AP bootstrap routines below 1 MB |
movq $BOOT_OFFSET, %rsi |
movq $AP_BOOT_OFFSET, %rdi |
movq $_hardcoded_unmapped_size, %rcx |
rep movsb |
#endif |
call main_bsp # never returns |
cli |
hlt |
/branches/dynload/kernel/arch/amd64/src/userspace.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
47,36 → 47,33 |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
ipl_t ipl; |
ipl_t ipl = interrupts_disable(); |
ipl = interrupts_disable(); |
/* Clear CF,PF,AF,ZF,SF,DF,OF */ |
/* Clear CF, PF, AF, ZF, SF, DF, OF */ |
ipl &= ~(0xcd4); |
asm volatile ("" |
"pushq %0\n" |
"pushq %1\n" |
"pushq %2\n" |
"pushq %3\n" |
"pushq %4\n" |
"movq %5, %%rax\n" |
/* %rdi is defined to hold pcb_ptr - set it to 0 */ |
"xorq %%rdi, %%rdi\n" |
"iretq\n" |
: : |
"i" (gdtselector(UDATA_DES) | PL_USER), |
"r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (gdtselector(UTEXT_DES) | PL_USER), |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg) |
: "rax" |
); |
asm volatile ( |
"pushq %[udata_des]\n" |
"pushq %[stack_size]\n" |
"pushq %[ipl]\n" |
"pushq %[utext_des]\n" |
"pushq %[entry]\n" |
"movq %[uarg], %%rax\n" |
/* %rdi is defined to hold pcb_ptr - set it to 0 */ |
"xorq %%rdi, %%rdi\n" |
"iretq\n" |
:: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER), |
[stack_size] "r" (kernel_uarg->uspace_stack + THREAD_STACK_SIZE), |
[ipl] "r" (ipl), |
[utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER), |
[entry] "r" (kernel_uarg->uspace_entry), |
[uarg] "r" (kernel_uarg->uspace_uarg) |
: "rax" |
); |
/* Unreachable */ |
for(;;) |
; |
while (1); |
} |
/** @} |
/branches/dynload/kernel/arch/mips32/include/types.h |
---|
57,10 → 57,6 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
typedef struct { |
} fncptr_t; |
/branches/dynload/kernel/arch/mips32/include/arch.h |
---|
38,6 → 38,8 |
#define TASKMAP_MAX_RECORDS 32 |
#define CPUMAP_MAX_RECORDS 32 |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
#include <typedefs.h> |
extern count_t cpu_count; |
45,6 → 47,7 |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
/branches/dynload/kernel/arch/mips32/include/asm.h |
---|
36,6 → 36,7 |
#define KERN_mips32_ASM_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <config.h> |
/branches/dynload/kernel/arch/mips32/src/asm.S |
---|
31,13 → 31,13 |
.text |
.macro cp0_read reg |
mfc0 $2,\reg |
mfc0 $2, \reg |
j $31 |
nop |
.endm |
.macro cp0_write reg |
mtc0 $4,\reg |
mtc0 $4, \reg |
j $31 |
nop |
.endm |
71,94 → 71,97 |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
addiu $v0,$a1,3 |
li $v1,-4 # 0xfffffffffffffffc |
and $v0,$v0,$v1 |
beq $a1,$v0,3f |
move $t0,$a0 |
move $t2,$a0 # save dst |
move $t2, $a0 # save dst |
addiu $v0, $a1, 3 |
li $v1, -4 # 0xfffffffffffffffc |
and $v0, $v0, $v1 |
beq $a1, $v0, 3f |
move $t0, $a0 |
0: |
beq $a2, $zero, 2f |
move $a3, $zero |
1: |
addu $v0, $a1, $a3 |
lbu $a0, 0($v0) |
addu $v1, $t0, $a3 |
addiu $a3, $a3, 1 |
bne $a3, $a2, 1b |
sb $a0, 0($v1) |
2: |
jr $ra |
move $v0, $t2 |
3: |
addiu $v0, $a0, 3 |
and $v0, $v0, $v1 |
bne $a0, $v0, 0b |
srl $t1, $a2, 2 |
beq $t1, $zero, 5f |
move $a3, $zero |
move $a3, $zero |
move $a0, $zero |
4: |
addu $v0, $a1, $a0 |
lw $v1, 0($v0) |
addiu $a3, $a3, 1 |
addu $v0, $t0, $a0 |
sw $v1, 0($v0) |
bne $a3, $t1, 4b |
addiu $a0, $a0, 4 |
5: |
andi $a2, $a2, 0x3 |
beq $a2, $zero, 2b |
nop |
sll $v0, $a3, 2 |
addu $t1, $v0, $t0 |
move $a3, $zero |
addu $t0, $v0, $a1 |
6: |
addu $v0, $t0, $a3 |
lbu $a0, 0($v0) |
addu $v1, $t1, $a3 |
addiu $a3, $a3, 1 |
bne $a3, $a2, 6b |
sb $a0, 0($v1) |
jr $ra |
move $v0, $t2 |
0: |
beq $a2,$zero,2f |
move $a3,$zero |
1: |
addu $v0,$a1,$a3 |
lbu $a0,0($v0) |
addu $v1,$t0,$a3 |
addiu $a3,$a3,1 |
bne $a3,$a2,1b |
sb $a0,0($v1) |
2: |
jr $ra |
move $v0,$t2 |
3: |
addiu $v0,$a0,3 |
and $v0,$v0,$v1 |
bne $a0,$v0,0b |
srl $t1,$a2,2 |
beq $t1,$zero,5f |
move $a3,$zero |
move $a3,$zero |
move $a0,$zero |
4: |
addu $v0,$a1,$a0 |
lw $v1,0($v0) |
addiu $a3,$a3,1 |
addu $v0,$t0,$a0 |
sw $v1,0($v0) |
bne $a3,$t1,4b |
addiu $a0,$a0,4 |
5: |
andi $a2,$a2,0x3 |
beq $a2,$zero,2b |
nop |
sll $v0,$a3,2 |
addu $t1,$v0,$t0 |
move $a3,$zero |
addu $t0,$v0,$a1 |
6: |
addu $v0,$t0,$a3 |
lbu $a0,0($v0) |
addu $v1,$t1,$a3 |
addiu $a3,$a3,1 |
bne $a3,$a2,6b |
sb $a0,0($v1) |
jr $ra |
move $v0,$t2 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
jr $ra |
move $v0, $zero |
jr $ra |
move $v0, $zero |
.macro fpu_gp_save reg ctx |
mfc1 $t0,$\reg |
sw $t0, \reg*4(\ctx) |
mfc1 $t0, $\reg |
sw $t0, \reg * 4(\ctx) |
.endm |
.macro fpu_gp_restore reg ctx |
lw $t0, \reg*4(\ctx) |
mtc1 $t0,$\reg |
lw $t0, \reg * 4(\ctx) |
mtc1 $t0, $\reg |
.endm |
.macro fpu_ct_save reg ctx |
cfc1 $t0,$1 |
sw $t0, (\reg+32)*4(\ctx) |
cfc1 $t0, $1 |
sw $t0, (\reg + 32) * 4(\ctx) |
.endm |
.macro fpu_ct_restore reg ctx |
lw $t0, (\reg+32)*4(\ctx) |
ctc1 $t0,$\reg |
lw $t0, (\reg + 32) * 4(\ctx) |
ctc1 $t0, $\reg |
.endm |
165,71 → 168,71 |
.global fpu_context_save |
fpu_context_save: |
#ifdef CONFIG_FPU |
fpu_gp_save 0,$a0 |
fpu_gp_save 1,$a0 |
fpu_gp_save 2,$a0 |
fpu_gp_save 3,$a0 |
fpu_gp_save 4,$a0 |
fpu_gp_save 5,$a0 |
fpu_gp_save 6,$a0 |
fpu_gp_save 7,$a0 |
fpu_gp_save 8,$a0 |
fpu_gp_save 9,$a0 |
fpu_gp_save 10,$a0 |
fpu_gp_save 11,$a0 |
fpu_gp_save 12,$a0 |
fpu_gp_save 13,$a0 |
fpu_gp_save 14,$a0 |
fpu_gp_save 15,$a0 |
fpu_gp_save 16,$a0 |
fpu_gp_save 17,$a0 |
fpu_gp_save 18,$a0 |
fpu_gp_save 19,$a0 |
fpu_gp_save 20,$a0 |
fpu_gp_save 21,$a0 |
fpu_gp_save 22,$a0 |
fpu_gp_save 23,$a0 |
fpu_gp_save 24,$a0 |
fpu_gp_save 25,$a0 |
fpu_gp_save 26,$a0 |
fpu_gp_save 27,$a0 |
fpu_gp_save 28,$a0 |
fpu_gp_save 29,$a0 |
fpu_gp_save 30,$a0 |
fpu_gp_save 31,$a0 |
fpu_ct_save 1,$a0 |
fpu_ct_save 2,$a0 |
fpu_ct_save 3,$a0 |
fpu_ct_save 4,$a0 |
fpu_ct_save 5,$a0 |
fpu_ct_save 6,$a0 |
fpu_ct_save 7,$a0 |
fpu_ct_save 8,$a0 |
fpu_ct_save 9,$a0 |
fpu_ct_save 10,$a0 |
fpu_ct_save 11,$a0 |
fpu_ct_save 12,$a0 |
fpu_ct_save 13,$a0 |
fpu_ct_save 14,$a0 |
fpu_ct_save 15,$a0 |
fpu_ct_save 16,$a0 |
fpu_ct_save 17,$a0 |
fpu_ct_save 18,$a0 |
fpu_ct_save 19,$a0 |
fpu_ct_save 20,$a0 |
fpu_ct_save 21,$a0 |
fpu_ct_save 22,$a0 |
fpu_ct_save 23,$a0 |
fpu_ct_save 24,$a0 |
fpu_ct_save 25,$a0 |
fpu_ct_save 26,$a0 |
fpu_ct_save 27,$a0 |
fpu_ct_save 28,$a0 |
fpu_ct_save 29,$a0 |
fpu_ct_save 30,$a0 |
fpu_ct_save 31,$a0 |
#endif |
fpu_gp_save 0, $a0 |
fpu_gp_save 1, $a0 |
fpu_gp_save 2, $a0 |
fpu_gp_save 3, $a0 |
fpu_gp_save 4, $a0 |
fpu_gp_save 5, $a0 |
fpu_gp_save 6, $a0 |
fpu_gp_save 7, $a0 |
fpu_gp_save 8, $a0 |
fpu_gp_save 9, $a0 |
fpu_gp_save 10, $a0 |
fpu_gp_save 11, $a0 |
fpu_gp_save 12, $a0 |
fpu_gp_save 13, $a0 |
fpu_gp_save 14, $a0 |
fpu_gp_save 15, $a0 |
fpu_gp_save 16, $a0 |
fpu_gp_save 17, $a0 |
fpu_gp_save 18, $a0 |
fpu_gp_save 19, $a0 |
fpu_gp_save 20, $a0 |
fpu_gp_save 21, $a0 |
fpu_gp_save 22, $a0 |
fpu_gp_save 23, $a0 |
fpu_gp_save 24, $a0 |
fpu_gp_save 25, $a0 |
fpu_gp_save 26, $a0 |
fpu_gp_save 27, $a0 |
fpu_gp_save 28, $a0 |
fpu_gp_save 29, $a0 |
fpu_gp_save 30, $a0 |
fpu_gp_save 31, $a0 |
fpu_ct_save 1, $a0 |
fpu_ct_save 2, $a0 |
fpu_ct_save 3, $a0 |
fpu_ct_save 4, $a0 |
fpu_ct_save 5, $a0 |
fpu_ct_save 6, $a0 |
fpu_ct_save 7, $a0 |
fpu_ct_save 8, $a0 |
fpu_ct_save 9, $a0 |
fpu_ct_save 10, $a0 |
fpu_ct_save 11, $a0 |
fpu_ct_save 12, $a0 |
fpu_ct_save 13, $a0 |
fpu_ct_save 14, $a0 |
fpu_ct_save 15, $a0 |
fpu_ct_save 16, $a0 |
fpu_ct_save 17, $a0 |
fpu_ct_save 18, $a0 |
fpu_ct_save 19, $a0 |
fpu_ct_save 20, $a0 |
fpu_ct_save 21, $a0 |
fpu_ct_save 22, $a0 |
fpu_ct_save 23, $a0 |
fpu_ct_save 24, $a0 |
fpu_ct_save 25, $a0 |
fpu_ct_save 26, $a0 |
fpu_ct_save 27, $a0 |
fpu_ct_save 28, $a0 |
fpu_ct_save 29, $a0 |
fpu_ct_save 30, $a0 |
fpu_ct_save 31, $a0 |
#endif |
j $ra |
nop |
236,70 → 239,70 |
.global fpu_context_restore |
fpu_context_restore: |
#ifdef CONFIG_FPU |
fpu_gp_restore 0,$a0 |
fpu_gp_restore 1,$a0 |
fpu_gp_restore 2,$a0 |
fpu_gp_restore 3,$a0 |
fpu_gp_restore 4,$a0 |
fpu_gp_restore 5,$a0 |
fpu_gp_restore 6,$a0 |
fpu_gp_restore 7,$a0 |
fpu_gp_restore 8,$a0 |
fpu_gp_restore 9,$a0 |
fpu_gp_restore 10,$a0 |
fpu_gp_restore 11,$a0 |
fpu_gp_restore 12,$a0 |
fpu_gp_restore 13,$a0 |
fpu_gp_restore 14,$a0 |
fpu_gp_restore 15,$a0 |
fpu_gp_restore 16,$a0 |
fpu_gp_restore 17,$a0 |
fpu_gp_restore 18,$a0 |
fpu_gp_restore 19,$a0 |
fpu_gp_restore 20,$a0 |
fpu_gp_restore 21,$a0 |
fpu_gp_restore 22,$a0 |
fpu_gp_restore 23,$a0 |
fpu_gp_restore 24,$a0 |
fpu_gp_restore 25,$a0 |
fpu_gp_restore 26,$a0 |
fpu_gp_restore 27,$a0 |
fpu_gp_restore 28,$a0 |
fpu_gp_restore 29,$a0 |
fpu_gp_restore 30,$a0 |
fpu_gp_restore 31,$a0 |
fpu_ct_restore 1,$a0 |
fpu_ct_restore 2,$a0 |
fpu_ct_restore 3,$a0 |
fpu_ct_restore 4,$a0 |
fpu_ct_restore 5,$a0 |
fpu_ct_restore 6,$a0 |
fpu_ct_restore 7,$a0 |
fpu_ct_restore 8,$a0 |
fpu_ct_restore 9,$a0 |
fpu_ct_restore 10,$a0 |
fpu_ct_restore 11,$a0 |
fpu_ct_restore 12,$a0 |
fpu_ct_restore 13,$a0 |
fpu_ct_restore 14,$a0 |
fpu_ct_restore 15,$a0 |
fpu_ct_restore 16,$a0 |
fpu_ct_restore 17,$a0 |
fpu_ct_restore 18,$a0 |
fpu_ct_restore 19,$a0 |
fpu_ct_restore 20,$a0 |
fpu_ct_restore 21,$a0 |
fpu_ct_restore 22,$a0 |
fpu_ct_restore 23,$a0 |
fpu_ct_restore 24,$a0 |
fpu_ct_restore 25,$a0 |
fpu_ct_restore 26,$a0 |
fpu_ct_restore 27,$a0 |
fpu_ct_restore 28,$a0 |
fpu_ct_restore 29,$a0 |
fpu_ct_restore 30,$a0 |
fpu_ct_restore 31,$a0 |
#endif |
fpu_gp_restore 0, $a0 |
fpu_gp_restore 1, $a0 |
fpu_gp_restore 2, $a0 |
fpu_gp_restore 3, $a0 |
fpu_gp_restore 4, $a0 |
fpu_gp_restore 5, $a0 |
fpu_gp_restore 6, $a0 |
fpu_gp_restore 7, $a0 |
fpu_gp_restore 8, $a0 |
fpu_gp_restore 9, $a0 |
fpu_gp_restore 10, $a0 |
fpu_gp_restore 11, $a0 |
fpu_gp_restore 12, $a0 |
fpu_gp_restore 13, $a0 |
fpu_gp_restore 14, $a0 |
fpu_gp_restore 15, $a0 |
fpu_gp_restore 16, $a0 |
fpu_gp_restore 17, $a0 |
fpu_gp_restore 18, $a0 |
fpu_gp_restore 19, $a0 |
fpu_gp_restore 20, $a0 |
fpu_gp_restore 21, $a0 |
fpu_gp_restore 22, $a0 |
fpu_gp_restore 23, $a0 |
fpu_gp_restore 24, $a0 |
fpu_gp_restore 25, $a0 |
fpu_gp_restore 26, $a0 |
fpu_gp_restore 27, $a0 |
fpu_gp_restore 28, $a0 |
fpu_gp_restore 29, $a0 |
fpu_gp_restore 30, $a0 |
fpu_gp_restore 31, $a0 |
fpu_ct_restore 1, $a0 |
fpu_ct_restore 2, $a0 |
fpu_ct_restore 3, $a0 |
fpu_ct_restore 4, $a0 |
fpu_ct_restore 5, $a0 |
fpu_ct_restore 6, $a0 |
fpu_ct_restore 7, $a0 |
fpu_ct_restore 8, $a0 |
fpu_ct_restore 9, $a0 |
fpu_ct_restore 10, $a0 |
fpu_ct_restore 11, $a0 |
fpu_ct_restore 12, $a0 |
fpu_ct_restore 13, $a0 |
fpu_ct_restore 14, $a0 |
fpu_ct_restore 15, $a0 |
fpu_ct_restore 16, $a0 |
fpu_ct_restore 17, $a0 |
fpu_ct_restore 18, $a0 |
fpu_ct_restore 19, $a0 |
fpu_ct_restore 20, $a0 |
fpu_ct_restore 21, $a0 |
fpu_ct_restore 22, $a0 |
fpu_ct_restore 23, $a0 |
fpu_ct_restore 24, $a0 |
fpu_ct_restore 25, $a0 |
fpu_ct_restore 26, $a0 |
fpu_ct_restore 27, $a0 |
fpu_ct_restore 28, $a0 |
fpu_ct_restore 29, $a0 |
fpu_ct_restore 30, $a0 |
fpu_ct_restore 31, $a0 |
#endif |
j $ra |
nop |
/branches/dynload/kernel/arch/mips32/src/mips32.c |
---|
54,6 → 54,8 |
#include <genarch/fb/visuals.h> |
#include <macros.h> |
#include <ddi/device.h> |
#include <config.h> |
#include <string.h> |
#include <arch/asm/regname.h> |
76,6 → 78,7 |
count_t cpu_count = 0; |
/** Performs mips32-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo) |
{ |
/* Setup usermode */ |
85,6 → 88,8 |
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) { |
init.tasks[i].addr = bootinfo->tasks[i].addr; |
init.tasks[i].size = bootinfo->tasks[i].size; |
strncpy(init.tasks[i].name, bootinfo->tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
for (i = 0; i < CPUMAP_MAX_RECORDS; i++) { |
/branches/dynload/kernel/arch/ia32/include/types.h |
---|
57,10 → 57,6 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
typedef struct { |
} fncptr_t; |
/branches/dynload/kernel/arch/ia32/include/cpuid.h |
---|
74,21 → 74,21 |
uint32_t val, ret; |
asm volatile ( |
"pushf\n" /* read flags */ |
"popl %0\n" |
"movl %0, %1\n" |
"pushf\n" /* read flags */ |
"popl %[ret]\n" |
"movl %[ret], %[val]\n" |
"btcl $21, %1\n" /* swap the ID bit */ |
"btcl $21, %[val]\n" /* swap the ID bit */ |
"pushl %1\n" /* propagate the change into flags */ |
"pushl %[val]\n" /* propagate the change into flags */ |
"popf\n" |
"pushf\n" |
"popl %1\n" |
"popl %[val]\n" |
"andl $(1 << 21), %0\n" /* interrested only in ID bit */ |
"andl $(1 << 21), %1\n" |
"xorl %1, %0\n" |
: "=r" (ret), "=r" (val) |
"andl $(1 << 21), %[ret]\n" /* interrested only in ID bit */ |
"andl $(1 << 21), %[val]\n" |
"xorl %[val], %[ret]\n" |
: [ret] "=r" (ret), [val] "=r" (val) |
); |
return ret; |
98,7 → 98,8 |
{ |
asm volatile ( |
"cpuid\n" |
: "=a" (info->cpuid_eax), "=b" (info->cpuid_ebx), "=c" (info->cpuid_ecx), "=d" (info->cpuid_edx) |
: "=a" (info->cpuid_eax), "=b" (info->cpuid_ebx), |
"=c" (info->cpuid_ecx), "=d" (info->cpuid_edx) |
: "a" (cmd) |
); |
} |
/branches/dynload/kernel/arch/ia32/include/atomic.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
41,17 → 41,29 |
static inline void atomic_inc(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ("lock incl %0\n" : "+m" (val->count)); |
asm volatile ( |
"lock incl %[count]\n" |
: [count] "+m" (val->count) |
); |
#else |
asm volatile ("incl %0\n" : "+m" (val->count)); |
asm volatile ( |
"incl %[count]\n" |
: [count] "+m" (val->count) |
); |
#endif /* CONFIG_SMP */ |
} |
static inline void atomic_dec(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ("lock decl %0\n" : "+m" (val->count)); |
asm volatile ( |
"lock decl %[count]\n" |
: [count] "+m" (val->count) |
); |
#else |
asm volatile ("decl %0\n" : "+m" (val->count)); |
asm volatile ( |
"decl %[count]\n" |
: "+m" (val->count) |
); |
#endif /* CONFIG_SMP */ |
} |
58,12 → 70,12 |
static inline long atomic_postinc(atomic_t *val) |
{ |
long r = 1; |
asm volatile ( |
"lock xaddl %1, %0\n" |
: "+m" (val->count), "+r" (r) |
"lock xaddl %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r" (r) |
); |
return r; |
} |
72,23 → 84,23 |
long r = -1; |
asm volatile ( |
"lock xaddl %1, %0\n" |
: "+m" (val->count), "+r"(r) |
"lock xaddl %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r"(r) |
); |
return r; |
} |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
static inline uint32_t test_and_set(atomic_t *val) { |
uint32_t v; |
asm volatile ( |
"movl $1, %0\n" |
"xchgl %0, %1\n" |
: "=r" (v),"+m" (val->count) |
"movl $1, %[v]\n" |
"xchgl %[v], %[count]\n" |
: [v] "=r" (v), [count] "+m" (val->count) |
); |
return v; |
98,22 → 110,22 |
static inline void atomic_lock_arch(atomic_t *val) |
{ |
uint32_t tmp; |
preemption_disable(); |
asm volatile ( |
"0:\n" |
#ifdef CONFIG_HT |
"pause\n" /* Pentium 4's HT love this instruction */ |
"pause\n" /* Pentium 4's HT love this instruction */ |
#endif |
"mov %0, %1\n" |
"testl %1, %1\n" |
"mov %[count], %[tmp]\n" |
"testl %[tmp], %[tmp]\n" |
"jnz 0b\n" /* lightweight looping on locked spinlock */ |
"incl %1\n" /* now use the atomic operation */ |
"xchgl %0, %1\n" |
"testl %1, %1\n" |
"incl %[tmp]\n" /* now use the atomic operation */ |
"xchgl %[count], %[tmp]\n" |
"testl %[tmp], %[tmp]\n" |
"jnz 0b\n" |
: "+m" (val->count), "=&r"(tmp) |
: [count] "+m" (val->count), [tmp] "=&r" (tmp) |
); |
/* |
* Prevent critical section code from bleeding out this way up. |
/branches/dynload/kernel/arch/ia32/include/boot/cboot.h |
---|
File deleted |
/branches/dynload/kernel/arch/ia32/include/boot/boot.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
35,15 → 35,24 |
#ifndef KERN_ia32_BOOT_H_ |
#define KERN_ia32_BOOT_H_ |
#define BOOT_OFFSET 0x108000 |
#define AP_BOOT_OFFSET 0x8000 |
#define BOOT_STACK_SIZE 0x400 |
#define BOOT_OFFSET 0x108000 |
#define AP_BOOT_OFFSET 0x8000 |
#define BOOT_STACK_SIZE 0x400 |
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 |
#define MULTIBOOT_HEADER_FLAGS 0x00010003 |
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 |
#define MULTIBOOT_HEADER_FLAGS 0x00010003 |
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002 |
#ifndef __ASM__ |
#ifdef CONFIG_SMP |
/* This is only a symbol so the type is dummy. Obtain the value using &. */ |
extern int _hardcoded_unmapped_size; |
#endif /* CONFIG_SMP */ |
#endif /* __ASM__ */ |
#endif |
/** @} |
/branches/dynload/kernel/arch/ia32/include/arch.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Martin Decky |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
35,6 → 35,10 |
#ifndef KERN_ia32_ARCH_H_ |
#define KERN_ia32_ARCH_H_ |
#include <genarch/multiboot/multiboot.h> |
extern void arch_pre_main(uint32_t, const multiboot_info_t *); |
#endif |
/** @} |
/branches/dynload/kernel/arch/ia32/include/asm.h |
---|
27,7 → 27,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
38,6 → 38,7 |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <config.h> |
extern uint32_t interrupt_handler_size; |
56,6 → 57,7 |
/** Halt CPU |
* |
* Halt the current CPU until interrupt event. |
* |
*/ |
static inline void cpu_halt(void) |
{ |
68,16 → 70,22 |
} |
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ |
{ \ |
unative_t res; \ |
asm volatile ("movl %%" #reg ", %0" : "=r" (res) ); \ |
return res; \ |
} |
{ \ |
unative_t res; \ |
asm volatile ( \ |
"movl %%" #reg ", %[res]" \ |
: [res] "=r" (res) \ |
); \ |
return res; \ |
} |
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \ |
{ \ |
asm volatile ("movl %0, %%" #reg : : "r" (regn)); \ |
} |
{ \ |
asm volatile ( \ |
"movl %[regn], %%" #reg \ |
:: [regn] "r" (regn) \ |
); \ |
} |
GEN_READ_REG(cr0) |
GEN_READ_REG(cr2) |
104,10 → 112,14 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_8(ioport8_t *port, uint8_t val) |
{ |
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port)); |
asm volatile ( |
"outb %b[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
/** Word to port |
116,10 → 128,14 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_16(ioport16_t *port, uint16_t val) |
{ |
asm volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port)); |
asm volatile ( |
"outw %w[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
/** Double word to port |
128,10 → 144,14 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_32(ioport32_t *port, uint32_t val) |
{ |
asm volatile ("outl %0, %w1\n" : : "a" (val), "d" (port)); |
asm volatile ( |
"outl %[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
/** Byte from port |
140,12 → 160,18 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
uint8_t val; |
asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port)); |
asm volatile ( |
"inb %w[port], %b[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
} |
155,12 → 181,18 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
uint16_t val; |
asm volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port)); |
asm volatile ( |
"inw %w[port], %w[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
} |
170,12 → 202,18 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
uint32_t val; |
asm volatile ("inl %w1, %0 \n" : "=a" (val) : "d" (port)); |
asm volatile ( |
"inl %w[port], %[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
} |
185,16 → 223,19 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_enable(void) |
{ |
ipl_t v; |
asm volatile ( |
"pushf\n\t" |
"popl %0\n\t" |
"pushf\n" |
"popl %[v]\n" |
"sti\n" |
: "=r" (v) |
: [v] "=r" (v) |
); |
return v; |
} |
204,16 → 245,19 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_disable(void) |
{ |
ipl_t v; |
asm volatile ( |
"pushf\n\t" |
"popl %0\n\t" |
"pushf\n" |
"popl %[v]\n" |
"cli\n" |
: "=r" (v) |
: [v] "=r" (v) |
); |
return v; |
} |
222,13 → 266,14 |
* Restore EFLAGS. |
* |
* @param ipl Saved interrupt priority level. |
* |
*/ |
static inline void interrupts_restore(ipl_t ipl) |
{ |
asm volatile ( |
"pushl %0\n\t" |
"pushl %[ipl]\n" |
"popf\n" |
: : "r" (ipl) |
:: [ipl] "r" (ipl) |
); |
} |
235,15 → 280,18 |
/** Return interrupt priority level. |
* |
* @return EFLAFS. |
* |
*/ |
static inline ipl_t interrupts_read(void) |
{ |
ipl_t v; |
asm volatile ( |
"pushf\n\t" |
"popl %0\n" |
: "=r" (v) |
"pushf\n" |
"popl %[v]\n" |
: [v] "=r" (v) |
); |
return v; |
} |
250,16 → 298,24 |
/** Write to MSR */ |
static inline void write_msr(uint32_t msr, uint64_t value) |
{ |
asm volatile ("wrmsr" : : "c" (msr), "a" ((uint32_t)(value)), |
"d" ((uint32_t)(value >> 32))); |
asm volatile ( |
"wrmsr" |
:: "c" (msr), "a" ((uint32_t) (value)), |
"d" ((uint32_t) (value >> 32)) |
); |
} |
static inline uint64_t read_msr(uint32_t msr) |
{ |
uint32_t ax, dx; |
asm volatile ("rdmsr" : "=a"(ax), "=d"(dx) : "c" (msr)); |
return ((uint64_t)dx << 32) | ax; |
asm volatile ( |
"rdmsr" |
: "=a" (ax), "=d" (dx) |
: "c" (msr) |
); |
return ((uint64_t) dx << 32) | ax; |
} |
268,6 → 324,7 |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
* |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
274,8 → 331,8 |
uintptr_t v; |
asm volatile ( |
"andl %%esp, %0\n" |
: "=r" (v) |
"andl %%esp, %[v]\n" |
: [v] "=r" (v) |
: "0" (~(STACK_SIZE - 1)) |
); |
286,11 → 343,12 |
static inline uintptr_t * get_ip() |
{ |
uintptr_t *ip; |
asm volatile ( |
"mov %%eip, %0" |
: "=r" (ip) |
); |
"mov %%eip, %[ip]" |
: [ip] "=r" (ip) |
); |
return ip; |
} |
297,46 → 355,66 |
/** Invalidate TLB Entry. |
* |
* @param addr Address on a page whose TLB entry is to be invalidated. |
* |
*/ |
static inline void invlpg(uintptr_t addr) |
{ |
asm volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr)); |
asm volatile ( |
"invlpg %[addr]\n" |
:: [addr] "m" (*(unative_t *) addr) |
); |
} |
/** Load GDTR register from memory. |
* |
* @param gdtr_reg Address of memory from where to load GDTR. |
* |
*/ |
static inline void gdtr_load(ptr_16_32_t *gdtr_reg) |
{ |
asm volatile ("lgdtl %0\n" : : "m" (*gdtr_reg)); |
asm volatile ( |
"lgdtl %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
} |
/** Store GDTR register to memory. |
* |
* @param gdtr_reg Address of memory to where to load GDTR. |
* |
*/ |
static inline void gdtr_store(ptr_16_32_t *gdtr_reg) |
{ |
asm volatile ("sgdtl %0\n" : : "m" (*gdtr_reg)); |
asm volatile ( |
"sgdtl %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
} |
/** Load IDTR register from memory. |
* |
* @param idtr_reg Address of memory from where to load IDTR. |
* |
*/ |
static inline void idtr_load(ptr_16_32_t *idtr_reg) |
{ |
asm volatile ("lidtl %0\n" : : "m" (*idtr_reg)); |
asm volatile ( |
"lidtl %[idtr_reg]\n" |
:: [idtr_reg] "m" (*idtr_reg) |
); |
} |
/** Load TR from descriptor table. |
* |
* @param sel Selector specifying descriptor of TSS segment. |
* |
*/ |
static inline void tr_load(uint16_t sel) |
{ |
asm volatile ("ltr %0" : : "r" (sel)); |
asm volatile ( |
"ltr %[sel]" |
:: [sel] "r" (sel) |
); |
} |
#endif |
/branches/dynload/kernel/arch/ia32/include/barrier.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
46,8 → 46,8 |
* Provisions are made to prevent compiler from reordering instructions itself. |
*/ |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
static inline void cpuid_serialization(void) |
{ |
70,29 → 70,29 |
} |
#if defined(CONFIG_FENCES_P4) |
# define memory_barrier() asm volatile ("mfence\n" ::: "memory") |
# define read_barrier() asm volatile ("lfence\n" ::: "memory") |
# ifdef CONFIG_WEAK_MEMORY |
# define write_barrier() asm volatile ("sfence\n" ::: "memory") |
# else |
# define write_barrier() asm volatile( "" ::: "memory"); |
# endif |
#define memory_barrier() asm volatile ("mfence\n" ::: "memory") |
#define read_barrier() asm volatile ("lfence\n" ::: "memory") |
#ifdef CONFIG_WEAK_MEMORY |
#define write_barrier() asm volatile ("sfence\n" ::: "memory") |
#else |
#define write_barrier() asm volatile ("" ::: "memory"); |
#endif |
#elif defined(CONFIG_FENCES_P3) |
# define memory_barrier() cpuid_serialization() |
# define read_barrier() cpuid_serialization() |
# ifdef CONFIG_WEAK_MEMORY |
# define write_barrier() asm volatile ("sfence\n" ::: "memory") |
# else |
# define write_barrier() asm volatile( "" ::: "memory"); |
# endif |
#define memory_barrier() cpuid_serialization() |
#define read_barrier() cpuid_serialization() |
#ifdef CONFIG_WEAK_MEMORY |
#define write_barrier() asm volatile ("sfence\n" ::: "memory") |
#else |
#define write_barrier() asm volatile ("" ::: "memory"); |
#endif |
#else |
# define memory_barrier() cpuid_serialization() |
# define read_barrier() cpuid_serialization() |
# ifdef CONFIG_WEAK_MEMORY |
# define write_barrier() cpuid_serialization() |
# else |
# define write_barrier() asm volatile( "" ::: "memory"); |
# endif |
#define memory_barrier() cpuid_serialization() |
#define read_barrier() cpuid_serialization() |
#ifdef CONFIG_WEAK_MEMORY |
#define write_barrier() cpuid_serialization() |
#else |
#define write_barrier() asm volatile ("" ::: "memory"); |
#endif |
#endif |
/* |
101,8 → 101,8 |
* queueing in the store buffer drain to the memory (even though it would be |
* sufficient for them to drain to the D-cache). |
*/ |
#define smc_coherence(a) write_barrier() |
#define smc_coherence_block(a, l) write_barrier() |
#define smc_coherence(a) write_barrier() |
#define smc_coherence_block(a, l) write_barrier() |
#endif |
/branches/dynload/kernel/arch/ia32/Makefile.inc |
---|
99,7 → 99,6 |
arch/$(KARCH)/src/drivers/i8259.c \ |
arch/$(KARCH)/src/drivers/vesa.c \ |
arch/$(KARCH)/src/boot/boot.S \ |
arch/$(KARCH)/src/boot/cboot.c \ |
arch/$(KARCH)/src/boot/memmap.c \ |
arch/$(KARCH)/src/fpu_context.c \ |
arch/$(KARCH)/src/debugger.c \ |
/branches/dynload/kernel/arch/ia32/src/fpu_context.c |
---|
44,46 → 44,43 |
static void fpu_context_f_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fnsave %0" |
: "=m"(*fctx) |
); |
"fnsave %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
static void fpu_context_f_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"frstor %0" |
: "=m"(*fctx) |
); |
"frstor %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
static void fpu_context_fx_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxsave %0" |
: "=m"(*fctx) |
); |
"fxsave %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
static void fpu_context_fx_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxrstor %0" |
: "=m"(*fctx) |
); |
"fxrstor %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
} |
/* |
Setup using fxsr instruction |
*/ |
/* Setup using fxsr instruction */ |
void fpu_fxsr(void) |
{ |
fpu_save=fpu_context_fx_save; |
fpu_restore=fpu_context_fx_restore; |
} |
/* |
Setup using not fxsr instruction |
*/ |
/* Setup using not fxsr instruction */ |
void fpu_fsr(void) |
{ |
fpu_save = fpu_context_f_save; |
102,16 → 99,18 |
void fpu_init() |
{ |
uint32_t help0 = 0, help1 = 0; |
uint32_t help0 = 0; |
uint32_t help1 = 0; |
asm volatile ( |
"fninit;\n" |
"stmxcsr %0\n" |
"mov %0,%1;\n" |
"or %2,%1;\n" |
"mov %1,%0;\n" |
"ldmxcsr %0;\n" |
: "+m" (help0), "+r" (help1) |
: "i" (0x1f80) |
"fninit\n" |
"stmxcsr %[help0]\n" |
"mov %[help0], %[help1]\n" |
"or %[magic], %[help1]\n" |
"mov %[help1], %[help0]\n" |
"ldmxcsr %[help0]\n" |
: [help0] "+m" (help0), [help1] "+r" (help1) |
: [magic] "i" (0x1f80) |
); |
} |
/branches/dynload/kernel/arch/ia32/src/ia32.c |
---|
1,5 → 1,7 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2009 Jiri Svoboda |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
38,6 → 40,7 |
#include <arch/pm.h> |
#include <genarch/multiboot/multiboot.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <genarch/drivers/ega/ega.h> |
#include <arch/drivers/vesa.h> |
63,11 → 66,29 |
#include <console/console.h> |
#include <ddi/device.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/boot/boot.h> |
#ifdef CONFIG_SMP |
#include <arch/smp/apic.h> |
#endif |
/** Perform ia32-specific initialization before main_bsp() is called. |
* |
* @param signature Should contain the multiboot signature. |
* @param mi Pointer to the multiboot information structure. |
*/ |
void arch_pre_main(uint32_t signature, const multiboot_info_t *mi) |
{ |
/* Parse multiboot information obtained from the bootloader. */ |
multiboot_info_parse(signature, mi); |
#ifdef CONFIG_SMP |
/* Copy AP bootstrap routines below 1 MB. */ |
memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET, |
(size_t) &_hardcoded_unmapped_size); |
#endif |
} |
void arch_pre_mm_init(void) |
{ |
pm_init(); |
136,6 → 157,10 |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
} |
void calibrate_delay_loop(void) |
/branches/dynload/kernel/arch/ia32/src/cpu/cpu.c |
---|
48,17 → 48,17 |
* Identification of CPUs. |
* Contains only non-MP-Specification specific SMP code. |
*/ |
#define AMD_CPUID_EBX 0x68747541 |
#define AMD_CPUID_ECX 0x444d4163 |
#define AMD_CPUID_EDX 0x69746e65 |
#define AMD_CPUID_EBX 0x68747541 |
#define AMD_CPUID_ECX 0x444d4163 |
#define AMD_CPUID_EDX 0x69746e65 |
#define INTEL_CPUID_EBX 0x756e6547 |
#define INTEL_CPUID_ECX 0x6c65746e |
#define INTEL_CPUID_EDX 0x49656e69 |
#define INTEL_CPUID_EBX 0x756e6547 |
#define INTEL_CPUID_ECX 0x6c65746e |
#define INTEL_CPUID_EDX 0x49656e69 |
enum vendor { |
VendorUnknown=0, |
VendorUnknown = 0, |
VendorAMD, |
VendorIntel |
}; |
72,12 → 72,10 |
void fpu_disable(void) |
{ |
asm volatile ( |
"mov %%cr0,%%eax;" |
"or $8,%%eax;" |
"mov %%eax,%%cr0;" |
: |
: |
: "%eax" |
"mov %%cr0, %%eax\n" |
"or $8, %%eax\n" |
"mov %%eax, %%cr0\n" |
::: "%eax" |
); |
} |
84,13 → 82,11 |
void fpu_enable(void) |
{ |
asm volatile ( |
"mov %%cr0,%%eax;" |
"and $0xffFFffF7,%%eax;" |
"mov %%eax,%%cr0;" |
: |
: |
: "%eax" |
); |
"mov %%cr0, %%eax\n" |
"and $0xffFFffF7, %%eax\n" |
"mov %%eax,%%cr0\n" |
::: "%eax" |
); |
} |
void cpu_arch_init(void) |
102,11 → 98,11 |
CPU->arch.tss = tss_p; |
CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((uint8_t *) CPU->arch.tss); |
CPU->fpu_owner = NULL; |
cpuid(1, &info); |
fi.word = info.cpuid_edx; |
efi.word = info.cpuid_ecx; |
113,15 → 109,15 |
if (fi.bits.fxsr) |
fpu_fxsr(); |
else |
fpu_fsr(); |
fpu_fsr(); |
if (fi.bits.sse) { |
asm volatile ( |
"mov %%cr4,%0\n" |
"or %1,%0\n" |
"mov %0,%%cr4\n" |
: "+r" (help) |
: "i" (CR4_OSFXSR_MASK|(1<<10)) |
"mov %%cr4, %[help]\n" |
"or %[mask], %[help]\n" |
"mov %[help], %%cr4\n" |
: [help] "+r" (help) |
: [mask] "i" (CR4_OSFXSR_MASK | (1 << 10)) |
); |
} |
/branches/dynload/kernel/arch/ia32/src/pm.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
154,7 → 154,7 |
"and $0xffff8fff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
: : : "eax" |
::: "eax" |
); |
} |
165,7 → 165,7 |
"mov %%cr0, %%eax\n" |
"and $0xfffbffff, %%eax\n" |
"mov %%eax, %%cr0\n" |
: : : "eax" |
::: "eax" |
); |
} |
/branches/dynload/kernel/arch/ia32/src/boot/cboot.c |
---|
File deleted |
/branches/dynload/kernel/arch/ia32/src/boot/boot.S |
---|
104,13 → 104,15 |
call map_kernel # map kernel and turn paging on |
# ia32_cboot(grub_eax, grub_ebx) |
# arch_pre_main(grub_eax, grub_ebx) |
pushl grub_ebx |
pushl grub_eax |
call ia32_cboot # Does not return. |
call arch_pre_main |
call main_bsp |
# Not reached. |
cli |
hlt |
/branches/dynload/kernel/arch/ia32/src/userspace.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
47,10 → 47,8 |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
ipl_t ipl = interrupts_disable(); |
asm volatile ( |
/* |
* Clear nested task flag. |
60,35 → 58,33 |
"and $0xffffbfff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
/* Set up GS register (TLS) */ |
"movl %6, %%gs\n" |
"pushl %0\n" |
"pushl %1\n" |
"pushl %2\n" |
"pushl %3\n" |
"pushl %4\n" |
"movl %5, %%eax\n" |
"movl %[tls_des], %%gs\n" |
"pushl %[udata_des]\n" |
"pushl %[stack_size]\n" |
"pushl %[ipl]\n" |
"pushl %[utext_des]\n" |
"pushl %[entry]\n" |
"movl %[uarg], %%eax\n" |
/* %ebx is defined to hold pcb_ptr - set it to 0 */ |
"xorl %%ebx, %%ebx\n" |
"xorl %%ebx, %%ebx\n" |
"iret\n" |
: |
: "i" (selector(UDATA_DES) | PL_USER), |
"r" ((uint8_t *) kernel_uarg->uspace_stack + |
THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (selector(UTEXT_DES) | PL_USER), |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg), |
"r" (selector(TLS_DES)) |
: |
: [udata_des] "i" (selector(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), |
[entry] "r" (kernel_uarg->uspace_entry), |
[uarg] "r" (kernel_uarg->uspace_uarg), |
[tls_des] "r" (selector(TLS_DES)) |
: "eax"); |
/* Unreachable */ |
for(;;) |
; |
while (1); |
} |
/** @} |
/branches/dynload/kernel/arch/ia32/src/interrupt.c |
---|
138,12 → 138,12 |
{ |
uint32_t mxcsr; |
asm ( |
"stmxcsr %0;\n" |
: "=m" (mxcsr) |
"stmxcsr %[mxcsr]\n" |
: [mxcsr] "=m" (mxcsr) |
); |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx.", |
(unative_t) mxcsr); |
decode_istate(istate); |
printf("MXCSR: %#lx\n", mxcsr); |
panic("SIMD FP exception(19)."); |