Merge branch 'master' into ohligs

Conflicts:
	.gitignore
This commit is contained in:
Marian Ohligs 2011-05-29 11:20:49 +02:00
commit 83f5a4c426
12 changed files with 242 additions and 19 deletions

View file

@ -39,6 +39,45 @@
extern "C" {
#endif
// feature list 1
#define CPU_FEATURE_FPU (1 << 0)
#define CPU_FEATURE_MMX (1 << 23)
#define CPU_FEATURE_FXSR (1 << 24)
#define CPU_FEATURE_SSE (1 << 25)
#define CPU_FEATURE_SSE2 (1 << 26)
// feature list 2
#define CPU_FEATURE_AVX (1 << 28)
typedef struct {
uint32_t feature1, feature2;
} cpu_info_t;
extern cpu_info_t cpu_info;
// determine the cpu features
int cpu_detection(void);
inline static uint32_t has_fpu(void)
{
return (cpu_info.feature1 & CPU_FEATURE_FPU);
}
inline static uint32_t has_fxsr(void)
{
return (cpu_info.feature1 & CPU_FEATURE_FXSR);
}
inline static uint32_t has_xmm(void)
{
return (cpu_info.feature1 & CPU_FEATURE_SSE);
}
inline static uint32_t has_avx(void)
{
return (cpu_info.feature2 & CPU_FEATURE_AVX);
}
/** @brief Read out time stamp counter
*
* The rdtsc asm command puts a 64 bit time stamp value
@ -250,6 +289,8 @@ inline static int system_init(void)
#ifdef CONFIG_PCI
pci_init();
#endif
cpu_detection();
return 0;
}

View file

@ -22,6 +22,7 @@
#define __ARCH_TASKS_TYPES__
#include <metalsvm/stddef.h>
#include <asm/processor.h>
#ifdef __cplusplus
extern "C" {
@ -61,7 +62,10 @@ union fpu_state {
};
static inline void save_fpu_state(union fpu_state* state) {
asm volatile ("fsave %0; fwait" : "=m"((*state).fsave));
if (has_fxsr())
asm volatile ("fxsave %0; fnclex" : "=m"((*state).fxsave));
else
asm volatile ("fsave %0; fwait" : "=m"((*state).fsave));
}
#ifdef __cplusplus

View file

@ -165,6 +165,26 @@ void isrs_install(void)
irq_install_handler(7, fpu_handler);
}
static void fpu_init(union fpu_state* fpu)
{
if (has_fxsr()) {
i387_fxsave_t* fx = &fpu->fxsave;
memset(fx, 0, sizeof(union fpu_state));
fx->cwd = 0x37f;
if (has_xmm)
fx->mxcsr = 0x1f80;
} else {
i387_fsave_t *fp = &fpu->fsave;
memset(fp, 0, sizeof(union fpu_state));
fp->cwd = 0xffff037fu;
fp->swd = 0xffff0000u;
fp->twd = 0xffffffffu;
fp->fos = 0xffff0000u;
}
}
static void fpu_handler(struct state *s)
{
task_t* task = per_core(current_task);
@ -172,13 +192,16 @@ static void fpu_handler(struct state *s)
asm volatile ("clts"); // clear the TS flag of cr0
if (!(task->flags & TASK_FPU_INIT)) {
// use the FPU at the first time => Initialize FPU
asm volatile ("finit");
task->flags = task->flags|TASK_FPU_INIT|TASK_FPU_USED;
} else {
// restore the FPU context
asm volatile ("frstor %0" :: "m"(task->fpu.fsave)); // restore fpu state
task->flags |= TASK_FPU_USED;
fpu_init(&task->fpu);
task->flags |= TASK_FPU_INIT;
}
// restore the FPU context
if (has_fxsr())
asm volatile ("fxrstor %0" :: "m"(task->fpu.fxsave));
else
asm volatile ("frstor %0" :: "m"(task->fpu.fsave));
task->flags |= TASK_FPU_USED;
}
/** @brief Exception messages

View file

@ -25,8 +25,31 @@
#include <asm/RCCE_lib.h>
#endif
cpu_info_t cpu_info = { 0, 0 };
static uint32_t cpu_freq = 0;
int cpu_detection(void)
{
uint32_t a, b, cr4;
cpuid(1, &a, &b, &cpu_info.feature2, &cpu_info.feature1);
cr4 = read_cr4();
if (has_fxsr())
cr4 |= 0x200; // set the OSFXSR bit
if (has_xmm())
cr4 |= 0x400; // set the OSXMMEXCPT bit
write_cr4(cr4);
if (has_avx())
kprintf("The CPU owns the Advanced Vector Extensions (AVX). However, MetalSVM doesn't support AVX!\n");
if (has_fpu())
asm volatile ("fninit");
return 0;
}
uint32_t detect_cpu_frequency(void)
{
#ifdef CONFIG_ROCKCREEK

View file

@ -209,15 +209,15 @@ int vga_puts(const char *text)
}
/* Sets the forecolor and backcolor we will use */
//void settextcolor(unsigned char forecolor, unsigned char backcolor)
//{
void settextcolor(unsigned char forecolor, unsigned char backcolor)
{
/*
* Top 4 bytes are the background, bottom 4 bytes
* are the foreground color
*/
// attrib = (backcolor << 4) | (forecolor & 0x0F);
//}
attrib = ((backcolor & 0x0F) << 4) | (forecolor & 0x0F);
}
/* Sets our text-mode VGA pointer, then clears the screen for us */
void vga_init(void)

View file

@ -337,7 +337,7 @@ int RCCE_init(
RCCE_shmalloc_init(RC_SHM_BUFFER_START()+RCCE_SHM_BUFFER_offset ,RCCE_SHM_SIZE_MAX);
#ifdef SHMDBG
printf("\n%d:%s:%d: RCCE_SHM_BUFFER_offset, RCCE_SHM_SIZE_MAX: % x %x\n", RCCE_IAM,
kprintf("\n%d:%s:%d: RCCE_SHM_BUFFER_offset, RCCE_SHM_SIZE_MAX: % x %x\n", RCCE_IAM,
__FILE__,__LINE__,RCCE_SHM_BUFFER_offset ,RCCE_SHM_SIZE_MAX);
#endif
#else
@ -439,8 +439,10 @@ int RCCE_num_ues(void) {return(RCCE_NP);}
//--------------------------------------------------------------------------------------
void writeLUT(unsigned int lutSlot, unsigned int value) {
int PAGE_SIZE, NCMDeviceFD;
#ifndef MS_BAREMETAL
int page_size, NCMDeviceFD;
// NCMDeviceFD is the file descriptor for non-cacheable memory (e.g. config regs).
#endif
unsigned int result;
@ -453,6 +455,7 @@ unsigned int myCoreID, alignedAddr, pageOffset, ConfigAddr;
else
ConfigAddr = CRB_OWN+LUT0 + (lutSlot*0x08);
#ifndef MS_BAREMETAL
PAGE_SIZE = getpagesize();
if ((NCMDeviceFD=open("/dev/rckncm", O_RDWR|O_SYNC))<0) {
@ -471,16 +474,19 @@ unsigned int myCoreID, alignedAddr, pageOffset, ConfigAddr;
*(int*)(MappedAddr+pageOffset) = value;
munmap((void*)MappedAddr, PAGE_SIZE);
#else
*(int*)(ConfigAddr) = value;
#endif
}
//--------------------------------------------------------------------------------------
// FUNCTION: readLUT
//--------------------------------------------------------------------------------------
unsigned int readLUT(unsigned int lutSlot) {
#ifndef MS_BAREMETAL
int PAGE_SIZE, NCMDeviceFD;
// NCMDeviceFD is the file descriptor for non-cacheable memory (e.g. config regs).
#endif
unsigned int result;
t_vcharp MappedAddr;
@ -492,6 +498,7 @@ unsigned int myCoreID, alignedAddr, pageOffset, ConfigAddr;
else
ConfigAddr = CRB_OWN+LUT0 + (lutSlot*0x08);
#ifndef MS_BAREMETAL
PAGE_SIZE = getpagesize();
if ((NCMDeviceFD=open("/dev/rckncm", O_RDWR|O_SYNC))<0) {
@ -510,6 +517,9 @@ unsigned int myCoreID, alignedAddr, pageOffset, ConfigAddr;
result = *(unsigned int*)(MappedAddr+pageOffset);
munmap((void*)MappedAddr, PAGE_SIZE);
#else
result = *(unsigned int*)(ConfigAddr);
#endif
return result;
}
@ -519,14 +529,16 @@ unsigned int myCoreID, alignedAddr, pageOffset, ConfigAddr;
//--------------------------------------------------------------------------------------
unsigned int getCOREID() {
#ifndef MS_BAREMETAL
int PAGE_SIZE, NCMDeviceFD;
// NCMDeviceFD is the file descriptor for non-cacheable memory (e.g. config regs).
#endif
t_vcharp MappedAddr;
unsigned int coreID,result, alignedAddr, pageOffset, ConfigAddr, coreID_mask=0x00000007;
ConfigAddr = CRB_OWN+MYTILEID;
#ifndef MS_BAREMETAL
PAGE_SIZE = getpagesize();
if ((NCMDeviceFD=open("/dev/rckncm", O_RDWR|O_SYNC))<0) {
@ -545,6 +557,9 @@ unsigned int coreID,result, alignedAddr, pageOffset, ConfigAddr, coreID_mask=0x
result = *(unsigned int*)(MappedAddr+pageOffset);
munmap((void*)MappedAddr, PAGE_SIZE);
#else
result = *(unsigned int*)(ConfigAddr);
#endif
coreID = result & coreID_mask;
return coreID;

View file

@ -56,7 +56,7 @@ void RCCE_shmalloc_init(
/* make a circular list by connecting tail to itself */
RCCE_spacep->tail->next = RCCE_spacep->tail;
#ifdef SHMDBG
printf("%s: %d: RCCE_spacep->tail->free_size, RCCE_spacep->tail->space: %x %x\n",
kprintf("%s: %d: RCCE_spacep->tail->free_size, RCCE_spacep->tail->space: %x %x\n",
__FILE__, __LINE__,RCCE_spacep->tail->free_size, RCCE_spacep->tail->space);
#endif
}

View file

@ -60,7 +60,8 @@ extern "C" {
#define SCC
#define MS_BAREMETAL
//#define GORY
//#define SHMADD
#define SHMADD
#define SHMDBG
//#define SHMADD_CACHEABLE
/* default values for 16 GB system */
#define PRIVATE_MEM1_START 0x00000000

View file

@ -74,6 +74,45 @@ int koutput_init(void);
*/
int kvprintf(char const *fmt, void (*func) (int, void *), void *arg, int radix, va_list ap);
/** @brief Set a new foreground color for kprintf and kputchar.
*
* The color change will affect any procedure using vga_putchar()/vga_puts().
* This procedure pushes the color onto a colorstack making you
* able to revert this change just with a popfg().
* */
void pushfg(unsigned char fgcol);
/** @brief Set a new background color for kprintf and kputchar.
*
* The color change will affect any procedure using vga_putchar()/vga_puts().
* This procedure pushes the color onto a colorstack making you
* able to revert this change just with a popbg().
* */
void pushbg(unsigned char bgcol);
#define COL_BLACK 0
#define COL_BLUE 1
#define COL_GREEN 2
#define COL_CYAN 3
#define COL_RED 4
#define COL_MAGENTA 5
#define COL_BROWN 6
#define COL_LGRAY 7
#define COL_DGRAY 8
#define COL_LBLUE 9
#define COL_LGREEN 10
#define COL_LCYAN 11
#define COL_LRED 12
#define COL_LMAGENTA 13
#define COL_LYELLOW 14
#define COL_WHITE 15
/** @brief Revert the last foreground color change introduced by pushfg() */
void popfg();
/** @brief Revert the last background color change introduced by pushfg() */
void popbg();
#ifdef __cplusplus
}
#endif

View file

@ -82,7 +82,10 @@ int main(void)
{
lowlevel_init();
kprintf("This is MetalSVM %s Build %u, %u\n", METALSVM_VERSION, &__BUILD_DATE, &__BUILD_TIME);
pushbg(COL_BLUE);
kprintf("This is MetalSVM %s Build %u, %u\n",
METALSVM_VERSION, &__BUILD_DATE, &__BUILD_TIME);
popbg();
system_init();
irq_init();

View file

@ -133,6 +133,7 @@ int test_init(void)
//create_user_task(NULL, "/bin/hello", argv);
create_user_task(NULL, "/bin/mshell", argv);
//create_user_task(NULL, "/bin/jacobi", argv);
//create_user_task(NULL, "/bin/jacobi", argv);
return 0;
}

View file

@ -45,6 +45,7 @@
*/
#include <metalsvm/string.h>
#include <metalsvm/spinlock.h>
#define __64BIT__
@ -74,6 +75,14 @@ char const hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz";
/* Max number conversion buffer length: a u_quad_t in base 2, plus NUL byte. */
#define MAXNBUF (sizeof(intmax_t) * NBBY + 1)
#define COLOR_STACK_SIZE 10
static int fgstack[COLOR_STACK_SIZE] = {0xf};
static int bgstack[COLOR_STACK_SIZE] = {0x0};
static unsigned int fgstack_pos = 0;
static unsigned int bgstack_pos = 0;
static spinlock_t fglock = SPINLOCK_INIT;
static spinlock_t bglock = SPINLOCK_INIT;
/*
* Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse
* order; return an optional length and a pointer to the last character
@ -483,3 +492,67 @@ int kprintf(const char *fmt, ...)
return ret;
}
#ifdef CONFIG_VGA
extern void settextcolor(unsigned char forecolor, unsigned char backcolor);
#endif
void pushfg(unsigned char fgcol)
{
spinlock_lock(&fglock);
/* Ignore this request if the stack is full */
if (fgstack_pos == COLOR_STACK_SIZE) goto rel_pushfglock;
++fgstack_pos;
fgstack[fgstack_pos] = fgcol;
#ifdef CONFIG_VGA
settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]);
#endif
rel_pushfglock:
spinlock_unlock(&fglock);
}
void pushbg(unsigned char bgcol)
{
spinlock_lock(&bglock);
/* Ignore this request if the stack is full */
if (bgstack_pos == COLOR_STACK_SIZE) goto rel_pushbglock;
++bgstack_pos;
bgstack[bgstack_pos] = bgcol;
#ifdef CONFIG_VGA
settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]);
#endif
rel_pushbglock:
spinlock_unlock(&bglock);
}
void popfg(void)
{
spinlock_lock(&fglock);
/* Ignore if we're already at the stack's bottom */
if (!fgstack_pos) goto rel_popfglock;
--fgstack_pos;
#ifdef CONFIG_VGA
settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]);
#endif
rel_popfglock:
spinlock_unlock(&fglock);
}
void popbg(void)
{
spinlock_lock(&bglock);
/* Ignore if we're already at the stack's bottom */
if (!bgstack_pos) goto rel_popbglock;
--bgstack_pos;
#ifdef CONFIG_VGA
settextcolor(fgstack[fgstack_pos], bgstack[bgstack_pos]);
#endif
rel_popbglock:
spinlock_unlock(&bglock);
}