/trunk/kernel/genarch/include/fb/font-8x16.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
35,11 → 35,14 |
#ifndef KERN_FONT_8X16_H_ |
#define KERN_FONT_8X16_H_ |
#define FONT_GLIPHS 256 |
#define FONT_SCANLINES 16 |
#define FONT_GLYPHS 256 |
#define FONT_WIDTH 8 |
#define FONT_SCANLINES 16 |
extern unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES]; |
#include <arch/types.h> |
extern uint8_t fb_font[FONT_GLYPHS * FONT_SCANLINES]; |
#endif |
/** @} |
/trunk/kernel/genarch/include/fb/visuals.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
35,15 → 35,15 |
#ifndef KERN_VISUALS_H_ |
#define KERN_VISUALS_H_ |
#define VISUAL_INDIRECT_8 0 |
#define VISUAL_INDIRECT_8 0 |
#define VISUAL_RGB_5_5_5 1 |
#define VISUAL_RGB_5_6_5 2 |
#define VISUAL_RGB_8_8_8 3 |
#define VISUAL_RGB_8_8_8_0 4 |
#define VISUAL_RGB_0_8_8_8 5 |
#define VISUAL_RGB_5_5_5 1 |
#define VISUAL_RGB_5_6_5 2 |
#define VISUAL_RGB_8_8_8 3 |
#define VISUAL_RGB_8_8_8_0 4 |
#define VISUAL_RGB_0_8_8_8 5 |
#define VISUAL_BGR_0_8_8_8 6 |
#define VISUAL_BGR_0_8_8_8 6 |
#endif |
/trunk/kernel/genarch/include/fb/fb.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
65,6 → 65,8 |
} fb_properties_t; |
SPINLOCK_EXTERN(fb_lock); |
void fb_redraw(void); |
void fb_init(fb_properties_t *props); |
#endif |
/trunk/kernel/genarch/src/fb/helenos.xbm |
---|
File deleted |
/trunk/kernel/genarch/src/fb/fb.c |
---|
1,4 → 1,5 |
/* |
* Copyright (c) 2008 Martin Decky |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
26,7 → 27,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
39,6 → 40,7 |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <mm/slab.h> |
#include <align.h> |
#include <panic.h> |
#include <memstr.h> |
#include <config.h> |
47,137 → 49,109 |
#include <ddi/ddi.h> |
#include <arch/types.h> |
#include "helenos.xbm" |
SPINLOCK_INITIALIZE(fb_lock); |
static parea_t fb_parea; /**< Physical memory area for fb. */ |
/**< Physical memory area for fb. */ |
static parea_t fb_parea; |
SPINLOCK_INITIALIZE(fb_lock); |
static uint8_t *fb_addr; |
static uint8_t *backbuf; |
static uint8_t *glyphs; |
static uint8_t *fbaddress = NULL; |
static void *bgpixel; |
static uint8_t *blankline = NULL; |
static uint8_t *dbbuffer = NULL; /* Buffer for fast scrolling console */ |
static index_t dboffset; |
static unsigned int xres; |
static unsigned int yres; |
static unsigned int xres = 0; |
static unsigned int yres = 0; |
static unsigned int scanline = 0; |
static unsigned int pixelbytes = 0; |
#ifdef FB_INVERT_COLORS |
static bool invert_colors = true; |
#else |
static bool invert_colors = false; |
#endif |
static unsigned int scanline; |
static unsigned int glyphscanline; |
static unsigned int pixelbytes; |
static unsigned int glyphbytes; |
static unsigned int cols; |
static unsigned int rows; |
static unsigned int position = 0; |
static unsigned int columns = 0; |
static unsigned int rows = 0; |
#define COL_WIDTH 8 |
#define ROW_BYTES (scanline * FONT_SCANLINES) |
#define BG_COLOR 0x000080 |
#define FG_COLOR 0xffff00 |
#define BGCOLOR 0x000080 |
#define FGCOLOR 0xffff00 |
#define LOGOCOLOR 0x2020b0 |
#define CURSOR 219 |
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
#define POINTPOS(x, y) ((y) * scanline + (x) * pixelbytes) |
#define COL2X(col) ((col) * FONT_WIDTH) |
#define ROW2Y(row) ((row) * FONT_SCANLINES) |
/***************************************************************/ |
/* Pixel specific fuctions */ |
#define X2COL(x) ((x) / FONT_WIDTH) |
#define Y2ROW(y) ((y) / FONT_SCANLINES) |
static void (*rgb2scr)(void *, int); |
static int (*scr2rgb)(void *); |
#define FB_POS(x, y) ((y) * scanline + (x) * pixelbytes) |
#define BB_POS(col, row) ((row) * cols + (col)) |
#define GLYPH_POS(glyph, y) ((glyph) * glyphbytes + (y) * glyphscanline) |
static inline int COLOR(int color) |
{ |
return invert_colors ? ~color : color; |
} |
/* Conversion routines between different color representations */ |
static void rgb_byte0888(void *dst, int rgb) |
{ |
*((int *) dst) = rgb; |
} |
static void (*rgb_conv)(void *, uint32_t); |
static int byte0888_rgb(void *src) |
{ |
return (*((int *) src)) & 0xffffff; |
} |
static void bgr_byte0888(void *dst, int rgb) |
/** ARGB 8:8:8:8 conversion |
* |
*/ |
static void rgb_0888(void *dst, uint32_t rgb) |
{ |
*((uint32_t *) dst) = BLUE(rgb, 8) << 16 | GREEN(rgb, 8) << 8 | |
RED(rgb, 8); |
*((uint32_t *) dst) = rgb & 0xffffff; |
} |
static int byte0888_bgr(void *src) |
/** ABGR 8:8:8:8 conversion |
* |
*/ |
static void bgr_0888(void *dst, uint32_t rgb) |
{ |
int color = *(uint32_t *)(src); |
return ((color & 0xff) << 16) | (((color >> 8) & 0xff) << 8) | |
((color >> 16) & 0xff); |
*((uint32_t *) dst) |
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8); |
} |
static void rgb_byte888(void *dst, int rgb) |
/** BGR 8:8:8 conversion |
* |
*/ |
static void rgb_888(void *dst, uint32_t rgb) |
{ |
uint8_t *scr = (uint8_t *) dst; |
#if defined(FB_INVERT_ENDIAN) |
scr[0] = RED(rgb, 8); |
scr[1] = GREEN(rgb, 8); |
scr[2] = BLUE(rgb, 8); |
*((uint32_t *) dst) |
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8) |
| (*((uint32_t *) dst) & 0xff0000); |
#else |
scr[2] = RED(rgb, 8); |
scr[1] = GREEN(rgb, 8); |
scr[0] = BLUE(rgb, 8); |
*((uint32_t *) dst) |
= (rgb & 0xffffff) | (*((uint32_t *) dst) & 0xff0000); |
#endif |
} |
static int byte888_rgb(void *src) |
{ |
uint8_t *scr = (uint8_t *) src; |
#if defined(FB_INVERT_ENDIAN) |
return scr[0] << 16 | scr[1] << 8 | scr[2]; |
#else |
return scr[2] << 16 | scr[1] << 8 | scr[0]; |
#endif |
} |
/** 16-bit depth (5:5:5) */ |
static void rgb_byte555(void *dst, int rgb) |
/** RGB 5:5:5 conversion |
* |
*/ |
static void rgb_555(void *dst, uint32_t rgb) |
{ |
/* 5-bit, 5-bits, 5-bits */ |
*((uint16_t *) dst) = RED(rgb, 5) << 10 | GREEN(rgb, 5) << 5 | |
BLUE(rgb, 5); |
*((uint16_t *) dst) |
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5); |
} |
/** 16-bit depth (5:5:5) */ |
static int byte555_rgb(void *src) |
{ |
int color = *(uint16_t *)(src); |
return (((color >> 10) & 0x1f) << (16 + 3)) | |
(((color >> 5) & 0x1f) << (8 + 3)) | ((color & 0x1f) << 3); |
} |
/** 16-bit depth (5:6:5) */ |
static void rgb_byte565(void *dst, int rgb) |
/** RGB 5:6:5 conversion |
* |
*/ |
static void rgb_565(void *dst, uint32_t rgb) |
{ |
/* 5-bit, 6-bits, 5-bits */ |
*((uint16_t *) dst) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 | |
BLUE(rgb, 5); |
*((uint16_t *) dst) |
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5); |
} |
/** 16-bit depth (5:6:5) */ |
static int byte565_rgb(void *src) |
{ |
int color = *(uint16_t *)(src); |
return (((color >> 11) & 0x1f) << (16 + 3)) | |
(((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3); |
} |
/** Put pixel - 8-bit depth (color palette/3:2:3, inverted) |
/** RGB 3:2:3 |
* |
* Even though we try 3:2:3 color scheme here, an 8-bit framebuffer |
* will most likely use a color palette. The color appearance |
185,7 → 159,7 |
* palette. This could be fixed by supporting custom palette |
* and setting it to simulate the 8-bit truecolor. |
* |
* Currently we set the palette on the sparc64 port. |
* Currently we set the palette on the ia32 and sparc64 port. |
* |
* Note that the byte is being inverted by this function. The reason is |
* that we would like to use a color palette where the white color code |
193,207 → 167,84 |
* use these codes for black and white and prevent to set codes |
* 0 and 255 to other colors. |
*/ |
static void rgb_byte8(void *dst, int rgb) |
static void rgb_323(void *dst, uint32_t rgb) |
{ |
*((uint8_t *) dst) = 255 - (RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 | |
BLUE(rgb, 3)); |
*((uint8_t *) dst) |
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3)); |
} |
/** Return pixel color - 8-bit depth (color palette/3:2:3) |
/** Draw character at given position |
* |
* See the comment for rgb_byte(). |
*/ |
static int byte8_rgb(void *src) |
static void draw_glyph(uint8_t glyph, unsigned int col, unsigned int row) |
{ |
int color = 255 - (*(uint8_t *)src); |
return (((color >> 5) & 0x7) << (16 + 5)) | |
(((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5); |
unsigned int x = COL2X(col); |
unsigned int y = ROW2Y(row); |
unsigned int yd; |
backbuf[BB_POS(col, row)] = glyph; |
for (yd = 0; yd < FONT_SCANLINES; yd++) |
memcpy(&fb_addr[FB_POS(x, y + yd)], |
&glyphs[GLYPH_POS(glyph, yd)], glyphscanline); |
} |
static void putpixel(unsigned int x, unsigned int y, int color) |
{ |
(*rgb2scr)(&fbaddress[POINTPOS(x, y)], COLOR(color)); |
if (dbbuffer) { |
int dline = (y + dboffset) % yres; |
(*rgb2scr)(&dbbuffer[POINTPOS(x, dline)], COLOR(color)); |
} |
} |
/** Get pixel from viewport */ |
static int getpixel(unsigned int x, unsigned int y) |
{ |
if (dbbuffer) { |
int dline = (y + dboffset) % yres; |
return COLOR((*scr2rgb)(&dbbuffer[POINTPOS(x, dline)])); |
} |
return COLOR((*scr2rgb)(&fbaddress[POINTPOS(x, y)])); |
} |
/** Fill screen with background color */ |
static void clear_screen(void) |
{ |
unsigned int y; |
for (y = 0; y < yres; y++) { |
memcpy(&fbaddress[scanline * y], blankline, xres * pixelbytes); |
if (dbbuffer) |
memcpy(&dbbuffer[scanline * y], blankline, |
xres * pixelbytes); |
} |
} |
/** Scroll screen one row up */ |
/** Scroll screen down by one row |
* |
* |
*/ |
static void scroll_screen(void) |
{ |
if (dbbuffer) { |
count_t first; |
unsigned int row; |
for (row = 0; row < rows; row++) { |
unsigned int y = ROW2Y(row); |
unsigned int yd; |
/* Clear the last row */ |
memcpy(&dbbuffer[dboffset * scanline], blankline, ROW_BYTES); |
dboffset = (dboffset + FONT_SCANLINES) % yres; |
first = yres - dboffset; |
/* Move all rows one row up */ |
if (xres * pixelbytes == scanline) { |
memcpy(fbaddress, &dbbuffer[dboffset * scanline], |
first * scanline); |
memcpy(&fbaddress[first * scanline], dbbuffer, |
dboffset * scanline); |
} else { |
/* |
* When the scanline is bigger than number of bytes |
* in the X-resolution, chances are that the |
* frame buffer memory past the X-resolution is special |
* in some way. For example, the SUNW,ffb framebuffer |
* wraps this area around the beginning of the same |
* line. To avoid troubles, copy only memory as |
* specified by the resolution. |
*/ |
unsigned int i; |
for (i = 0; i < first; i++) |
memcpy(&fbaddress[i * scanline], |
&dbbuffer[(dboffset + i) * scanline], |
xres * pixelbytes); |
for (i = 0; i < dboffset; i++) |
memcpy(&fbaddress[(first + i) * scanline], |
&dbbuffer[i * scanline], xres * pixelbytes); |
for (yd = 0; yd < FONT_SCANLINES; yd++) { |
unsigned int x; |
unsigned int col; |
for (col = 0, x = 0; col < cols; col++, x += FONT_WIDTH) { |
uint8_t glyph; |
if (row < rows - 1) { |
if (backbuf[BB_POS(col, row)] == backbuf[BB_POS(col, row + 1)]) |
continue; |
glyph = backbuf[BB_POS(col, row + 1)]; |
} else |
glyph = 0; |
memcpy(&fb_addr[FB_POS(x, y + yd)], |
&glyphs[GLYPH_POS(glyph, yd)], glyphscanline); |
} |
} |
} else { |
uint8_t *lastline = &fbaddress[(rows - 1) * ROW_BYTES]; |
if (xres * pixelbytes == scanline) { |
/* Move all rows one row up */ |
memcpy((void *) fbaddress, |
(void *) &fbaddress[ROW_BYTES], |
scanline * yres - ROW_BYTES); |
/* Clear the last row */ |
memcpy((void *) lastline, (void *) blankline, |
ROW_BYTES); |
} else { |
/* |
* See the comment in the dbbuffer case. |
*/ |
unsigned int i; |
/* Move all rows one row up */ |
for (i = 0; i < yres - FONT_SCANLINES; i++) |
memcpy(&fbaddress[i * scanline], |
&fbaddress[(i + FONT_SCANLINES) * scanline], |
xres * pixelbytes); |
/* Clear the last row */ |
for (i = 0; i < FONT_SCANLINES; i++) |
memcpy(&lastline[i * scanline], |
&blankline[i * scanline], |
xres * pixelbytes); |
} |
} |
memcpy(backbuf, backbuf + cols, cols * (rows - 1)); |
memsetb(&backbuf[BB_POS(0, rows - 1)], cols, 0); |
} |
static void invert_pixel(unsigned int x, unsigned int y) |
static void cursor_put(void) |
{ |
putpixel(x, y, ~getpixel(x, y)); |
draw_glyph(CURSOR, position % cols, position / cols); |
} |
/** Draw one line of glyph at a given position */ |
static void draw_glyph_line(unsigned int glline, unsigned int x, unsigned int y) |
static void cursor_remove(void) |
{ |
unsigned int i; |
for (i = 0; i < 8; i++) |
if (glline & (1 << (7 - i))) { |
putpixel(x + i, y, FGCOLOR); |
} else |
putpixel(x + i, y, BGCOLOR); |
draw_glyph(0, position % cols, position / cols); |
} |
/***************************************************************/ |
/* Character-console functions */ |
/** Draw character at given position */ |
static void draw_glyph(uint8_t glyph, unsigned int col, unsigned int row) |
{ |
unsigned int y; |
for (y = 0; y < FONT_SCANLINES; y++) |
draw_glyph_line(fb_font[glyph * FONT_SCANLINES + y], |
col * COL_WIDTH, row * FONT_SCANLINES + y); |
} |
/** Invert character at given position */ |
static void invert_char(unsigned int col, unsigned int row) |
{ |
unsigned int x; |
unsigned int y; |
for (x = 0; x < COL_WIDTH; x++) |
for (y = 0; y < FONT_SCANLINES; y++) |
invert_pixel(col * COL_WIDTH + x, |
row * FONT_SCANLINES + y); |
} |
/** Draw character at default position */ |
static void draw_char(char chr) |
{ |
draw_glyph(chr, position % columns, position / columns); |
} |
static void draw_logo(unsigned int startx, unsigned int starty) |
{ |
unsigned int x; |
unsigned int y; |
unsigned int byte; |
unsigned int rowbytes; |
rowbytes = (helenos_width - 1) / 8 + 1; |
for (y = 0; y < helenos_height; y++) |
for (x = 0; x < helenos_width; x++) { |
byte = helenos_bits[rowbytes * y + x / 8]; |
byte >>= x % 8; |
if (byte & 1) |
putpixel(startx + x, starty + y, |
COLOR(LOGOCOLOR)); |
} |
} |
/***************************************************************/ |
/* Stdout specific functions */ |
static void invert_cursor(void) |
{ |
invert_char(position % columns, position / columns); |
} |
/** Print character to screen |
* |
* Emulate basic terminal commands |
* Emulate basic terminal commands. |
* |
*/ |
static void fb_putchar(chardev_t *dev, char ch) |
{ |
401,37 → 252,37 |
switch (ch) { |
case '\n': |
invert_cursor(); |
position += columns; |
position -= position % columns; |
cursor_remove(); |
position += cols; |
position -= position % cols; |
break; |
case '\r': |
invert_cursor(); |
position -= position % columns; |
cursor_remove(); |
position -= position % cols; |
break; |
case '\b': |
invert_cursor(); |
if (position % columns) |
cursor_remove(); |
if (position % cols) |
position--; |
break; |
case '\t': |
invert_cursor(); |
cursor_remove(); |
do { |
draw_char(' '); |
draw_glyph((uint8_t) ' ', position % cols, position / cols); |
position++; |
} while ((position % 8) && position < columns * rows); |
} while ((position % 8) && (position < cols * rows)); |
break; |
default: |
draw_char(ch); |
draw_glyph((uint8_t) ch, position % cols, position / cols); |
position++; |
} |
if (position >= columns * rows) { |
position -= columns; |
if (position >= cols * rows) { |
position -= cols; |
scroll_screen(); |
} |
invert_cursor(); |
cursor_put(); |
spinlock_unlock(&fb_lock); |
} |
442,46 → 293,116 |
}; |
/** Render glyphs |
* |
* Convert glyphs from device independent font |
* description to current visual representation. |
* |
*/ |
static void render_glyphs(void) |
{ |
unsigned int glyph; |
for (glyph = 0; glyph < FONT_GLYPHS; glyph++) { |
unsigned int y; |
for (y = 0; y < FONT_SCANLINES; y++) { |
unsigned int x; |
for (x = 0; x < FONT_WIDTH; x++) |
rgb_conv(&glyphs[GLYPH_POS(glyph, y) + x * pixelbytes], |
(fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) ? FG_COLOR : BG_COLOR); |
} |
} |
rgb_conv(bgpixel, BG_COLOR); |
} |
/** Refresh the screen |
* |
*/ |
void fb_redraw(void) |
{ |
unsigned int row; |
for (row = 0; row < rows; row++) { |
unsigned int y = ROW2Y(row); |
unsigned int yd; |
for (yd = 0; yd < FONT_SCANLINES; yd++) { |
unsigned int x; |
unsigned int col; |
for (col = 0, x = 0; col < cols; col++, x += FONT_WIDTH) |
memcpy(&fb_addr[FB_POS(x, y + yd)], |
&glyphs[GLYPH_POS(backbuf[BB_POS(col, row)], yd)], |
glyphscanline); |
} |
} |
if (COL2X(cols) < xres) { |
unsigned int y; |
for (y = 0; y < yres; y++) { |
unsigned int x; |
for (x = COL2X(cols); x < xres; x++) |
memcpy(&fb_addr[FB_POS(x, y)], bgpixel, pixelbytes); |
} |
} |
if (ROW2Y(rows) < yres) { |
unsigned int y; |
for (y = ROW2Y(rows); y < yres; y++) { |
unsigned int x; |
for (x = 0; x < xres; x++) |
memcpy(&fb_addr[FB_POS(x, y)], bgpixel, pixelbytes); |
} |
} |
} |
/** Initialize framebuffer as a chardev output device |
* |
* @param props Properties of the framebuffer device. |
* @param addr Physical address of the framebuffer |
* @param x Screen width in pixels |
* @param y Screen height in pixels |
* @param scan Bytes per one scanline |
* @param visual Color model |
* |
*/ |
void fb_init(fb_properties_t *props) |
{ |
switch (props->visual) { |
case VISUAL_INDIRECT_8: |
rgb2scr = rgb_byte8; |
scr2rgb = byte8_rgb; |
rgb_conv = rgb_323; |
pixelbytes = 1; |
break; |
case VISUAL_RGB_5_5_5: |
rgb2scr = rgb_byte555; |
scr2rgb = byte555_rgb; |
rgb_conv = rgb_555; |
pixelbytes = 2; |
break; |
case VISUAL_RGB_5_6_5: |
rgb2scr = rgb_byte565; |
scr2rgb = byte565_rgb; |
rgb_conv = rgb_565; |
pixelbytes = 2; |
break; |
case VISUAL_RGB_8_8_8: |
rgb2scr = rgb_byte888; |
scr2rgb = byte888_rgb; |
rgb_conv = rgb_888; |
pixelbytes = 3; |
break; |
case VISUAL_RGB_8_8_8_0: |
rgb2scr = rgb_byte888; |
scr2rgb = byte888_rgb; |
rgb_conv = rgb_888; |
pixelbytes = 4; |
break; |
case VISUAL_RGB_0_8_8_8: |
rgb2scr = rgb_byte0888; |
scr2rgb = byte0888_rgb; |
rgb_conv = rgb_0888; |
pixelbytes = 4; |
break; |
case VISUAL_BGR_0_8_8_8: |
rgb2scr = bgr_byte0888; |
scr2rgb = byte0888_bgr; |
rgb_conv = bgr_0888; |
pixelbytes = 4; |
break; |
default: |
488,60 → 409,56 |
panic("Unsupported visual.\n"); |
} |
unsigned int fbsize = props->scan * props->y; |
/* Map the framebuffer */ |
fbaddress = (uint8_t *) hw_map((uintptr_t) props->addr, |
fbsize + props->offset); |
fbaddress += props->offset; |
xres = props->x; |
yres = props->y; |
scanline = props->scan; |
rows = props->y / FONT_SCANLINES; |
columns = props->x / COL_WIDTH; |
cols = xres / FONT_WIDTH; |
rows = yres / FONT_SCANLINES; |
glyphscanline = FONT_WIDTH * pixelbytes; |
glyphbytes = glyphscanline * FONT_SCANLINES; |
unsigned int fbsize = scanline * yres; |
unsigned int bbsize = cols * rows; |
unsigned int glyphsize = FONT_GLYPHS * glyphbytes; |
backbuf = (uint8_t *) malloc(bbsize, 0); |
if (!backbuf) |
panic("Unable to allocate backbuffer.\n"); |
glyphs = (uint8_t *) malloc(glyphsize, 0); |
if (!glyphs) |
panic("Unable to allocate glyphs.\n"); |
bgpixel = malloc(pixelbytes, 0); |
if (!bgpixel) |
panic("Unable to allocate background pixel.\n"); |
memsetb(backbuf, bbsize, 0); |
memsetb(glyphs, glyphsize, 0); |
memsetb(bgpixel, pixelbytes, 0); |
render_glyphs(); |
fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize); |
fb_parea.pbase = (uintptr_t) props->addr + props->offset; |
fb_parea.vbase = (uintptr_t) fbaddress; |
fb_parea.vbase = (uintptr_t) fb_addr; |
fb_parea.frames = SIZE2FRAMES(fbsize); |
fb_parea.cacheable = false; |
ddi_parea_register(&fb_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 1); |
sysinfo_set_item_val("fb.width", NULL, xres); |
sysinfo_set_item_val("fb.height", NULL, yres); |
sysinfo_set_item_val("fb.scanline", NULL, props->scan); |
sysinfo_set_item_val("fb.scanline", NULL, scanline); |
sysinfo_set_item_val("fb.visual", NULL, props->visual); |
sysinfo_set_item_val("fb.address.physical", NULL, props->addr); |
sysinfo_set_item_val("fb.offset", NULL, props->offset); |
sysinfo_set_item_val("fb.invert-colors", NULL, invert_colors); |
/* Allocate double buffer */ |
unsigned int order = fnzb(SIZE2FRAMES(fbsize) - 1) + 1; |
dbbuffer = (uint8_t *) frame_alloc(order, FRAME_ATOMIC | FRAME_KA); |
if (!dbbuffer) |
printf("Failed to allocate scroll buffer.\n"); |
dboffset = 0; |
/* Initialized blank line */ |
blankline = (uint8_t *) malloc(ROW_BYTES, FRAME_ATOMIC); |
if (!blankline) |
panic("Failed to allocate blank line for framebuffer."); |
unsigned int x, y; |
for (y = 0; y < FONT_SCANLINES; y++) |
for (x = 0; x < xres; x++) |
(*rgb2scr)(&blankline[POINTPOS(x, y)], COLOR(BGCOLOR)); |
clear_screen(); |
/* Update size of screen to match text area */ |
yres = rows * FONT_SCANLINES; |
draw_logo(xres - helenos_width, 0); |
invert_cursor(); |
fb_redraw(); |
chardev_initialize("fb", &framebuffer, &fb_ops); |
stdout = &framebuffer; |
} |
/trunk/kernel/genarch/src/fb/font-8x16.c |
---|
34,7 → 34,7 |
#include <genarch/fb/font-8x16.h> |
unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES] = { |
uint8_t fb_font[FONT_GLYPHS * FONT_SCANLINES] = { |
/* 0 0x00 '^@' */ |
0x00, /* 00000000 */ |
/trunk/kernel/genarch/src/mm/asid.c |
---|
32,7 → 32,7 |
/** |
* @file |
* @brief ASID management. |
* @brief ASID management. |
* |
* Modern processor architectures optimize TLB utilization |
* by using ASIDs (a.k.a. memory contexts on sparc64 and |
/trunk/kernel/genarch/src/acpi/acpi.c |
---|
49,8 → 49,12 |
struct acpi_rsdt *acpi_rsdt = NULL; |
struct acpi_xsdt *acpi_xsdt = NULL; |
struct acpi_signature_map signature_map[] = { |
{ (uint8_t *)"APIC", (void *) &acpi_madt, "Multiple APIC Description Table" } |
struct acpi_signature_map signature_map[] = { |
{ |
(uint8_t *) "APIC", |
(void *) &acpi_madt, |
"Multiple APIC Description Table" |
} |
}; |
static int rsdp_check(uint8_t *rsdp) { |
105,7 → 109,7 |
if (!acpi_sdt_check((uint8_t *) h)) |
goto next; |
*signature_map[j].sdt_ptr = h; |
printf("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description); |
LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description); |
} |
} |
next: |
126,7 → 130,7 |
if (!acpi_sdt_check((uint8_t *) h)) |
goto next; |
*signature_map[j].sdt_ptr = h; |
printf("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description); |
LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description); |
} |
} |
next: |
160,7 → 164,7 |
return; |
rsdp_found: |
printf("%p: ACPI Root System Description Pointer\n", acpi_rsdp); |
LOG("%p: ACPI Root System Description Pointer\n", acpi_rsdp); |
acpi_rsdt = (struct acpi_rsdt *) (unative_t) acpi_rsdp->rsdt_address; |
if (acpi_rsdp->revision) acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address); |
/trunk/kernel/generic/include/console/kconsole.h |
---|
87,7 → 87,8 |
extern link_t cmd_head; |
extern void kconsole_init(void); |
extern void kconsole(void *prompt); |
extern void kconsole(char *prompt, char *msg, bool kcon); |
extern void kconsole_thread(void *data); |
extern int cmd_register(cmd_info_t *cmd); |
/trunk/kernel/generic/src/main/kinit.c |
---|
82,8 → 82,11 |
*/ |
void kinit(void *arg) |
{ |
thread_t *t; |
#if defined(CONFIG_SMP) || defined(CONFIG_KCONSOLE) |
thread_t *thread; |
#endif |
/* |
* Detach kinit as nobody will call thread_join_timeout() on it. |
*/ |
100,23 → 103,19 |
* not mess together with kcpulb threads. |
* Just a beautification. |
*/ |
if ((t = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED, |
"kmp", true))) { |
spinlock_lock(&t->lock); |
t->cpu = &cpus[0]; |
spinlock_unlock(&t->lock); |
thread_ready(t); |
thread = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED, "kmp", true); |
if (thread != NULL) { |
spinlock_lock(&thread->lock); |
thread->cpu = &cpus[0]; |
spinlock_unlock(&thread->lock); |
thread_ready(thread); |
} else |
panic("thread_create/kmp\n"); |
thread_join(t); |
thread_detach(t); |
panic("Unable to create kmp thread\n"); |
thread_join(thread); |
thread_detach(thread); |
} |
#endif /* CONFIG_SMP */ |
/* |
* Now that all CPUs are up, we can report what we've found. |
*/ |
cpu_list(); |
#ifdef CONFIG_SMP |
if (config.cpu_count > 1) { |
count_t i; |
125,35 → 124,37 |
* For each CPU, create its load balancing thread. |
*/ |
for (i = 0; i < config.cpu_count; i++) { |
if ((t = thread_create(kcpulb, NULL, TASK, |
THREAD_FLAG_WIRED, "kcpulb", true))) { |
spinlock_lock(&t->lock); |
t->cpu = &cpus[i]; |
spinlock_unlock(&t->lock); |
thread_ready(t); |
thread = thread_create(kcpulb, NULL, TASK, THREAD_FLAG_WIRED, "kcpulb", true); |
if (thread != NULL) { |
spinlock_lock(&thread->lock); |
thread->cpu = &cpus[i]; |
spinlock_unlock(&thread->lock); |
thread_ready(thread); |
} else |
panic("thread_create/kcpulb\n"); |
printf("Unable to create kcpulb thread for cpu" PRIc "\n", i); |
} |
} |
#endif /* CONFIG_SMP */ |
/* |
* At this point SMP, if present, is configured. |
*/ |
arch_post_smp_init(); |
/* |
* Create kernel console. |
*/ |
t = thread_create(kconsole, (void *) "kconsole", TASK, 0, "kconsole", |
false); |
if (t) |
thread_ready(t); |
else |
panic("thread_create/kconsole\n"); |
#ifdef CONFIG_KCONSOLE |
if (stdin) { |
/* |
* Create kernel console. |
*/ |
thread = thread_create(kconsole_thread, NULL, TASK, 0, "kconsole", false); |
if (thread != NULL) |
thread_ready(thread); |
else |
printf("Unable to create kconsole thread\n"); |
} |
#endif /* CONFIG_KCONSOLE */ |
interrupts_enable(); |
/* |
164,14 → 165,14 |
for (i = 0; i < init.cnt; i++) { |
if (init.tasks[i].addr % FRAME_SIZE) { |
printf("init[%" PRIc "].addr is not frame aligned", i); |
printf("init[%" PRIc "].addr is not frame aligned\n", i); |
continue; |
} |
int rc = program_create_from_image((void *) init.tasks[i].addr, |
"init-bin", &programs[i]); |
if (rc == 0 && programs[i].task != NULL) { |
if ((rc == 0) && (programs[i].task != NULL)) { |
/* |
* Set capabilities to init userspace tasks. |
*/ |
184,12 → 185,10 |
/* It was the program loader and was registered */ |
} else { |
/* RAM disk image */ |
int rd = init_rd((rd_header_t *) init.tasks[i].addr, |
init.tasks[i].size); |
int rd = init_rd((rd_header_t *) init.tasks[i].addr, init.tasks[i].size); |
if (rd != RE_OK) |
printf("Init binary %" PRIc " not used, error " |
"code %d.\n", i, rd); |
printf("Init binary %" PRIc " not used (error %d)\n", i, rd); |
} |
} |
203,12 → 202,18 |
} |
} |
#ifdef CONFIG_KCONSOLE |
if (!stdin) { |
printf("kinit: No stdin\nKernel alive: "); |
uint64_t i = 0; |
while (1) { |
printf(PRIu64 " ", i); |
thread_sleep(1); |
printf("kinit... "); |
i++; |
} |
} |
#endif /* CONFIG_KCONSOLE */ |
} |
/** @} |
/trunk/kernel/generic/src/main/main.c |
---|
191,8 → 191,6 |
{ |
/* Keep this the first thing. */ |
the_initialize(THE); |
LOG(); |
version_print(); |
200,8 → 198,8 |
"\nconfig.stack_base=%#" PRIp " config.stack_size=%" PRIs, |
config.base, config.kernel_size, config.stack_base, |
config.stack_size); |
#ifdef CONFIG_KCONSOLE |
/* |
* kconsole data structures must be initialized very early |
* because other subsystems will register their respective |
208,6 → 206,7 |
* commands. |
*/ |
LOG_EXEC(kconsole_init()); |
#endif |
/* |
* Exception handler initialization, before architecture |
252,7 → 251,7 |
if (init.cnt > 0) { |
count_t i; |
for (i = 0; i < init.cnt; i++) |
printf("init[%" PRIc "].addr=%#" PRIp ", init[%" PRIc |
LOG("init[%" PRIc "].addr=%#" PRIp ", init[%" PRIc |
"].size=%#" PRIs "\n", i, init.tasks[i].addr, i, |
init.tasks[i].size); |
} else |
271,8 → 270,8 |
/* |
* Create the first thread. |
*/ |
thread_t *kinit_thread = thread_create(kinit, NULL, kernel, 0, "kinit", |
true); |
thread_t *kinit_thread |
= thread_create(kinit, NULL, kernel, 0, "kinit", true); |
if (!kinit_thread) |
panic("Can't create kinit thread\n"); |
LOG_EXEC(thread_ready(kinit_thread)); |
/trunk/kernel/generic/src/cpu/cpu.c |
---|
86,7 → 86,7 |
} |
#endif /* CONFIG_SMP */ |
CPU = &cpus[config.cpu_active-1]; |
CPU = &cpus[config.cpu_active - 1]; |
CPU->active = 1; |
CPU->tlb_active = 1; |
/trunk/kernel/generic/src/interrupt/interrupt.c |
---|
109,8 → 109,10 |
panic("Unhandled exception %d.", n); |
} |
#ifdef CONFIG_KCONSOLE |
/** kconsole cmd - print all exceptions */ |
static int exc_print_cmd(cmd_arg_t *argv) |
static int cmd_exc_print(cmd_arg_t *argv) |
{ |
#if (IVT_ITEMS > 0) |
unsigned int i; |
158,15 → 160,18 |
return 1; |
} |
static cmd_info_t exc_info = { |
.name = "exc", |
.description = "Print exception table.", |
.func = exc_print_cmd, |
.func = cmd_exc_print, |
.help = NULL, |
.argc = 0, |
.argv = NULL |
}; |
#endif |
/** Initialize generic exception handling support */ |
void exc_init(void) |
{ |
175,9 → 180,11 |
for (i = 0; i < IVT_ITEMS; i++) |
exc_register(i, "undef", (iroutine) exc_undef); |
#ifdef CONFIG_KCONSOLE |
cmd_initialize(&exc_info); |
if (!cmd_register(&exc_info)) |
panic("could not register command %s\n", exc_info.name); |
printf("Cannot register command %s\n", exc_info.name); |
#endif |
} |
/** @} |
/trunk/kernel/generic/src/console/console.c |
---|
167,7 → 167,7 |
printf("cpu%u: ", CPU->id); |
else |
printf("cpu: "); |
printf("halted - no kconsole\n"); |
printf("halted (no kconsole)\n"); |
cpu_halt(); |
} |
/trunk/kernel/generic/src/console/cmd.c |
---|
501,7 → 501,7 |
for (i = 0; basic_commands[i]; i++) { |
cmd_initialize(basic_commands[i]); |
if (!cmd_register(basic_commands[i])) |
panic("could not register command %s\n", basic_commands[i]->name); |
printf("Cannot register command %s\n", basic_commands[i]->name); |
} |
} |
/trunk/kernel/generic/src/console/kconsole.c |
---|
401,11 → 401,15 |
return current; |
} |
/** Kernel console managing thread. |
/** Kernel console prompt. |
* |
* @param prompt Kernel console prompt (e.g kconsole/panic). |
* @param msg Message to display in the beginning. |
* @param kcon Wait for keypress to show the prompt |
* and never exit. |
* |
*/ |
void kconsole(void *prompt) |
void kconsole(char *prompt, char *msg, bool kcon) |
{ |
cmd_info_t *cmd_info; |
count_t len; |
412,25 → 416,42 |
char *cmdline; |
if (!stdin) { |
printf("%s: no stdin\n", __func__); |
LOG("No stdin for kernel console"); |
return; |
} |
if (msg) |
printf("%s", msg); |
if (kcon) |
_getc(stdin); |
while (true) { |
cmdline = clever_readline((char *) prompt, stdin); |
len = strlen(cmdline); |
if (!len) |
continue; |
cmd_info = parse_cmdline(cmdline, len); |
if (!cmd_info) |
continue; |
if (strncmp(cmd_info->name, "exit", |
min(strlen(cmd_info->name), 5)) == 0) |
if ((!kcon) |
&& (strncmp(cmd_info->name, "exit", min(strlen(cmd_info->name), 5)) == 0)) |
break; |
(void) cmd_info->func(cmd_info->argv); |
} |
} |
/** Kernel console managing thread. |
* |
*/ |
void kconsole_thread(void *data) |
{ |
kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true); |
} |
static int parse_int_arg(char *text, size_t len, unative_t *result) |
{ |
static char symname[MAX_SYMBOL_NAME]; |
/trunk/kernel/generic/src/lib/func.c |
---|
55,8 → 55,6 |
#ifdef CONFIG_DEBUG |
bool rundebugger = false; |
// TODO test_and_set not defined on all arches |
// if (!test_and_set(&haltstate)) |
if (!atomic_get(&haltstate)) { |
atomic_set(&haltstate, 1); |
rundebugger = true; |
66,12 → 64,12 |
#endif |
interrupts_disable(); |
#ifdef CONFIG_DEBUG |
if (rundebugger) { |
printf("\n"); |
kconsole("panic"); /* Run kconsole as a last resort to user */ |
} |
#endif |
#if (defined(CONFIG_DEBUG)) && (defined(CONFIG_KCONSOLE)) |
if (rundebugger) |
kconsole("panic", "\nLast resort kernel console ready\n", false); |
#endif |
if (CPU) |
printf("cpu%u: halted\n", CPU->id); |
else |
/trunk/kernel/generic/src/mm/as.c |
---|
146,8 → 146,12 |
AS_KERNEL = as_create(FLAG_AS_KERNEL); |
if (!AS_KERNEL) |
panic("can't create kernel address space\n"); |
panic("Cannot create kernel address space\n"); |
/* Make sure the kernel address space |
* reference count never drops to zero. |
*/ |
atomic_set(&AS_KERNEL->refcount, 1); |
} |
/** Create address space. |
176,7 → 180,7 |
#else |
page_table_create(flags); |
#endif |
return as; |
} |
769,11 → 773,12 |
* In order for this to work properly, this may copy the data |
* into private anonymous memory (unless it's already there). |
* |
* @param as Address space. |
* @param flags Flags of the area memory. |
* @param address Address withing the area to be changed. |
* @param as Address space. |
* @param flags Flags of the area memory. |
* @param address Address within the area to be changed. |
* |
* @return Zero on success or a value from @ref errno.h on failure. |
* @return Zero on success or a value from @ref errno.h on failure. |
* |
*/ |
int as_area_change_flags(as_t *as, int flags, uintptr_t address) |
{ |
785,7 → 790,7 |
uintptr_t *old_frame; |
index_t frame_idx; |
count_t used_pages; |
/* Flags for the new memory mapping */ |
page_flags = area_flags_to_page_flags(flags); |
799,7 → 804,7 |
return ENOENT; |
} |
if (area->sh_info || area->backend != &anon_backend) { |
if ((area->sh_info) || (area->backend != &anon_backend)) { |
/* Copying shared areas not supported yet */ |
/* Copying non-anonymous memory not supported yet */ |
mutex_unlock(&area->lock); |
870,6 → 875,7 |
*/ |
tlb_invalidate_pages(as->asid, area->base, area->pages); |
/* |
* Invalidate potential software translation caches (e.g. TSB on |
* sparc64). |
/trunk/kernel/generic/src/syscall/syscall.c |
---|
92,8 → 92,12 |
/** Tell kernel to get keyboard/console access again */ |
static unative_t sys_debug_enable_console(void) |
{ |
#ifdef CONFIG_KCONSOLE |
arch_grab_console(); |
return 0; |
return true; |
#else |
return false; |
#endif |
} |
/** Dispatch system call */ |
/trunk/kernel/arch/amd64/src/debugger.c |
---|
54,6 → 54,8 |
static bpinfo_t breakpoints[BKPOINTS_MAX]; |
SPINLOCK_INITIALIZE(bkpoint_lock); |
#ifdef CONFIG_KCONSOLE |
static int cmd_print_breakpoints(cmd_arg_t *argv); |
static cmd_info_t bkpts_info = { |
.name = "bkpts", |
99,44 → 101,9 |
.argv = &addw_argv |
}; |
#endif |
#endif /* CONFIG_DEBUG_AS_WATCHPOINT */ |
#endif /* CONFIG_KCONSOLE */ |
/** Print table of active breakpoints */ |
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused))) |
{ |
unsigned int i; |
char *symbol; |
#ifdef __32_BITS__ |
printf("# Count Address In symbol\n"); |
printf("-- ----- ---------- ---------\n"); |
#endif |
#ifdef __64_BITS__ |
printf("# Count Address In symbol\n"); |
printf("-- ----- ------------------ ---------\n"); |
#endif |
for (i = 0; i < BKPOINTS_MAX; i++) |
if (breakpoints[i].address) { |
symbol = get_symtab_entry(breakpoints[i].address); |
#ifdef __32_BITS__ |
printf("%-2u %-5d %#10zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
#ifdef __64_BITS__ |
printf("%-2u %-5d %#18zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
} |
return 1; |
} |
/* Setup DR register according to table */ |
static void setup_dr(int curidx) |
{ |
267,10 → 234,12 |
} |
printf("Reached breakpoint %d:%lx(%s)\n", slot, getip(istate), |
get_symtab_entry(getip(istate))); |
printf("***Type 'exit' to exit kconsole.\n"); |
atomic_set(&haltstate,1); |
kconsole((void *) "debug"); |
atomic_set(&haltstate,0); |
#ifdef CONFIG_KCONSOLE |
atomic_set(&haltstate, 1); |
kconsole("debug", "Debug console ready (type 'exit' to continue)\n", false); |
atomic_set(&haltstate, 0); |
#endif |
} |
void breakpoint_del(int slot) |
299,42 → 268,8 |
#endif |
} |
#ifndef CONFIG_DEBUG_AS_WATCHPOINT |
/** Remove breakpoint from table */ |
int cmd_del_breakpoint(cmd_arg_t *argv) |
{ |
unative_t bpno = argv->intval; |
if (bpno > BKPOINTS_MAX) { |
printf("Invalid breakpoint number.\n"); |
return 0; |
} |
breakpoint_del(argv->intval); |
return 1; |
} |
/** Add new breakpoint to table */ |
static int cmd_add_breakpoint(cmd_arg_t *argv) |
{ |
int flags; |
int id; |
if (argv == &add_argv) { |
flags = BKPOINT_INSTR; |
} else { /* addwatchp */ |
flags = BKPOINT_WRITE; |
} |
printf("Adding breakpoint on address: %p\n", argv->intval); |
id = breakpoint_add((void *)argv->intval, flags, -1); |
if (id < 0) |
printf("Add breakpoint failed.\n"); |
else |
printf("Added breakpoint %d.\n", id); |
return 1; |
} |
#endif |
static void debug_exception(int n __attribute__((unused)), istate_t *istate) |
{ |
unative_t dr6; |
379,24 → 314,26 |
for (i = 0; i < BKPOINTS_MAX; i++) |
breakpoints[i].address = NULL; |
#ifdef CONFIG_KCONSOLE |
cmd_initialize(&bkpts_info); |
if (!cmd_register(&bkpts_info)) |
panic("could not register command %s\n", bkpts_info.name); |
printf("Cannot register command %s\n", bkpts_info.name); |
#ifndef CONFIG_DEBUG_AS_WATCHPOINT |
cmd_initialize(&delbkpt_info); |
if (!cmd_register(&delbkpt_info)) |
panic("could not register command %s\n", delbkpt_info.name); |
printf("Cannot register command %s\n", delbkpt_info.name); |
cmd_initialize(&addbkpt_info); |
if (!cmd_register(&addbkpt_info)) |
panic("could not register command %s\n", addbkpt_info.name); |
printf("Cannot register command %s\n", addbkpt_info.name); |
cmd_initialize(&addwatchp_info); |
if (!cmd_register(&addwatchp_info)) |
panic("could not register command %s\n", addwatchp_info.name); |
#endif |
printf("Cannot register command %s\n", addwatchp_info.name); |
#endif /* CONFIG_DEBUG_AS_WATCHPOINT */ |
#endif /* CONFIG_KCONSOLE */ |
exc_register(VECTOR_DEBUG, "debugger", debug_exception); |
#ifdef CONFIG_SMP |
404,5 → 341,79 |
#endif |
} |
#ifdef CONFIG_KCONSOLE |
/** Print table of active breakpoints */ |
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused))) |
{ |
unsigned int i; |
char *symbol; |
#ifdef __32_BITS__ |
printf("# Count Address In symbol\n"); |
printf("-- ----- ---------- ---------\n"); |
#endif |
#ifdef __64_BITS__ |
printf("# Count Address In symbol\n"); |
printf("-- ----- ------------------ ---------\n"); |
#endif |
for (i = 0; i < BKPOINTS_MAX; i++) |
if (breakpoints[i].address) { |
symbol = get_symtab_entry(breakpoints[i].address); |
#ifdef __32_BITS__ |
printf("%-2u %-5d %#10zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
#ifdef __64_BITS__ |
printf("%-2u %-5d %#18zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
} |
return 1; |
} |
#ifndef CONFIG_DEBUG_AS_WATCHPOINT |
/** Remove breakpoint from table */ |
int cmd_del_breakpoint(cmd_arg_t *argv) |
{ |
unative_t bpno = argv->intval; |
if (bpno > BKPOINTS_MAX) { |
printf("Invalid breakpoint number.\n"); |
return 0; |
} |
breakpoint_del(argv->intval); |
return 1; |
} |
/** Add new breakpoint to table */ |
static int cmd_add_breakpoint(cmd_arg_t *argv) |
{ |
int flags; |
int id; |
if (argv == &add_argv) { |
flags = BKPOINT_INSTR; |
} else { /* addwatchp */ |
flags = BKPOINT_WRITE; |
} |
printf("Adding breakpoint on address: %p\n", argv->intval); |
id = breakpoint_add((void *)argv->intval, flags, -1); |
if (id < 0) |
printf("Add breakpoint failed.\n"); |
else |
printf("Added breakpoint %d.\n", id); |
return 1; |
} |
#endif /* CONFIG_DEBUG_AS_WATCHPOINT */ |
#endif /* CONFIG_KCONSOLE */ |
/** @} |
*/ |
/trunk/kernel/arch/mips32/src/exception.c |
---|
45,7 → 45,6 |
#include <print.h> |
#include <interrupt.h> |
#include <func.h> |
#include <console/kconsole.h> |
#include <ddi/irq.h> |
#include <arch/debugger.h> |
/trunk/kernel/arch/mips32/src/cpu/cpu.c |
---|
48,7 → 48,7 |
{ "MIPS", "R2000" }, /* 0x01 */ |
{ "MIPS", "R3000" }, /* 0x02 */ |
{ "MIPS", "R6000" }, /* 0x03 */ |
{ "MIPS", " R4000/R4400" }, /* 0x04 */ |
{ "MIPS", "R4000/R4400" }, /* 0x04 */ |
{ "LSI Logic", "R3000" }, /* 0x05 */ |
{ "MIPS", "R6000A" }, /* 0x06 */ |
{ "IDT", "3051/3052" }, /* 0x07 */ |
123,9 → 123,9 |
data = &imp_data[m->arch.imp_num]; |
} |
printf("cpu%d: %s %s (rev=%d.%d, imp=%d)\n", |
printf("cpu%u: %s %s (rev=%d.%d, imp=%d)\n", |
m->id, data->vendor, data->model, m->arch.rev_num >> 4, |
m->arch.rev_num & 0xf, m->arch.imp_num); |
m->arch.rev_num & 0x0f, m->arch.imp_num); |
} |
/** @} |
/trunk/kernel/arch/mips32/src/debugger.c |
---|
47,6 → 47,8 |
bpinfo_t breakpoints[BKPOINTS_MAX]; |
SPINLOCK_INITIALIZE(bkpoint_lock); |
#ifdef CONFIG_KCONSOLE |
static int cmd_print_breakpoints(cmd_arg_t *argv); |
static cmd_info_t bkpts_info = { |
.name = "bkpts", |
123,10 → 125,12 |
{0, 0} /* EndOfTable */ |
}; |
/** Test, if the given instruction is a jump or branch instruction |
* |
* @param instr Instruction code |
* @return true - it is jump instruction, false otherwise |
* |
*/ |
static bool is_jump(unative_t instr) |
{ |
267,6 → 271,8 |
return 1; |
} |
#endif |
/** Initialize debugger */ |
void debugger_init() |
{ |
274,22 → 280,24 |
for (i = 0; i < BKPOINTS_MAX; i++) |
breakpoints[i].address = NULL; |
#ifdef CONFIG_KCONSOLE |
cmd_initialize(&bkpts_info); |
if (!cmd_register(&bkpts_info)) |
panic("could not register command %s\n", bkpts_info.name); |
printf("Cannot register command %s\n", bkpts_info.name); |
cmd_initialize(&delbkpt_info); |
if (!cmd_register(&delbkpt_info)) |
panic("could not register command %s\n", delbkpt_info.name); |
printf("Cannot register command %s\n", delbkpt_info.name); |
cmd_initialize(&addbkpt_info); |
if (!cmd_register(&addbkpt_info)) |
panic("could not register command %s\n", addbkpt_info.name); |
printf("Cannot register command %s\n", addbkpt_info.name); |
cmd_initialize(&addbkpte_info); |
if (!cmd_register(&addbkpte_info)) |
panic("could not register command %s\n", addbkpte_info.name); |
printf("Cannot register command %s\n", addbkpte_info.name); |
#endif |
} |
/** Handle breakpoint |
367,19 → 375,20 |
if (cur->bkfunc) |
cur->bkfunc(cur, istate); |
} else { |
printf("***Type 'exit' to exit kconsole.\n"); |
#ifdef CONFIG_KCONSOLE |
/* This disables all other processors - we are not SMP, |
* actually this gets us to cpu_halt, if scheduler() is run |
* - we generally do not want scheduler to be run from debug, |
* so this is a good idea |
*/ |
atomic_set(&haltstate,1); |
atomic_set(&haltstate, 1); |
spinlock_unlock(&bkpoint_lock); |
kconsole("debug"); |
kconsole("debug", "Debug console ready (type 'exit' to continue)\n", false); |
spinlock_lock(&bkpoint_lock); |
atomic_set(&haltstate,0); |
atomic_set(&haltstate, 0); |
#endif |
} |
if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) { |
/* Remove one-shot breakpoint */ |
/trunk/kernel/arch/ia32/include/drivers/ega.h |
---|
40,6 → 40,7 |
#define ROWS 25 |
#define SCREEN (ROW * ROWS) |
extern void ega_redraw(void); |
extern void ega_init(void); |
#endif |
/trunk/kernel/arch/ia32/include/drivers/vesa.h |
---|
36,6 → 36,7 |
#define KERN_ia32_VESA_H_ |
extern int vesa_present(void); |
extern void vesa_redraw(void); |
extern void vesa_init(void); |
#endif |
/trunk/kernel/arch/ia32/src/ia32.c |
---|
93,7 → 93,7 |
vesa_init(); |
else |
#endif |
ega_init(); /* video */ |
ega_init(); /* video */ |
/* Enable debugger */ |
debugger_init(); |
159,8 → 159,15 |
*/ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
vesa_redraw(); |
#else |
ega_redraw(); |
#endif |
i8042_grab(); |
} |
/** Return console to userspace |
* |
*/ |
/trunk/kernel/arch/ia32/src/cpu/cpu.c |
---|
65,8 → 65,8 |
static char *vendor_str[] = { |
"Unknown Vendor", |
"AuthenticAMD", |
"GenuineIntel" |
"AMD", |
"Intel" |
}; |
void fpu_disable(void) |
77,7 → 77,7 |
"mov %%eax,%%cr0;" |
: |
: |
:"%eax" |
: "%eax" |
); |
} |
89,7 → 89,7 |
"mov %%eax,%%cr0;" |
: |
: |
:"%eax" |
: "%eax" |
); |
} |
140,29 → 140,31 |
/* |
* Check for AMD processor. |
*/ |
if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) { |
if ((info.cpuid_ebx == AMD_CPUID_EBX) |
&& (info.cpuid_ecx == AMD_CPUID_ECX) |
&& (info.cpuid_edx == AMD_CPUID_EDX)) |
CPU->arch.vendor = VendorAMD; |
} |
/* |
* Check for Intel processor. |
*/ |
if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) { |
if ((info.cpuid_ebx == INTEL_CPUID_EBX) |
&& (info.cpuid_ecx == INTEL_CPUID_ECX) |
&& (info.cpuid_edx == INTEL_CPUID_EDX)) |
CPU->arch.vendor = VendorIntel; |
} |
cpuid(1, &info); |
CPU->arch.family = (info.cpuid_eax>>8)&0xf; |
CPU->arch.model = (info.cpuid_eax>>4)&0xf; |
CPU->arch.stepping = (info.cpuid_eax>>0)&0xf; |
CPU->arch.family = (info.cpuid_eax >> 8) & 0x0f; |
CPU->arch.model = (info.cpuid_eax >> 4) & 0x0f; |
CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0f; |
} |
} |
void cpu_print_report(cpu_t* m) |
void cpu_print_report(cpu_t* cpu) |
{ |
printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n", |
m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping, |
m->frequency_mhz); |
printf("cpu%u: (%s family=%u model=%u stepping=%u) %" PRIu16 " MHz\n", |
cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family, |
cpu->arch.model, cpu->arch.stepping, cpu->frequency_mhz); |
} |
/** @} |
/trunk/kernel/arch/ia32/src/drivers/vesa.c |
---|
97,6 → 97,11 |
fb_init(&vesa_props); |
} |
void vesa_redraw(void) |
{ |
fb_redraw(); |
} |
#endif |
/** @} |