diff --git a/src/arch/i386/lib/params.c b/src/arch/i386/lib/params.c index 8e26098ff3..ad83fd4821 100644 --- a/src/arch/i386/lib/params.c +++ b/src/arch/i386/lib/params.c @@ -1,5 +1,9 @@ #include +#ifdef VIDEO_CONSOLE +#include +#endif + /* This software and ancillary information (herein called SOFTWARE ) called LinuxBIOS is made available under the terms described @@ -148,13 +152,23 @@ get_empty_zero_page() /* I am pretty sure we only need to set rows and cols for now. * All the rest is BIOS stuff. If it gets worse we'll have to make this a * screen_info * as the param + * S. Gehlbach: added additional items needed for video console */ +extern int video_line,video_col; void set_display(unsigned char *empty_zero_page, int rows, int cols) { struct screen_info *sc = &SCREEN_INFO; sc->orig_video_cols = cols; sc->orig_video_lines = rows; + +#ifdef VIDEO_CONSOLE + sc->orig_video_isVGA = 1; + sc->orig_video_points = CHAR_HEIGHT; + sc->orig_video_mode = 3; + sc->orig_x = video_col; + sc->orig_y = video_line; +#endif } void diff --git a/src/include/pc80/ide.h b/src/include/pc80/ide.h index 715aba9d3f..f720e25390 100644 --- a/src/include/pc80/ide.h +++ b/src/include/pc80/ide.h @@ -47,7 +47,7 @@ typedef struct { unsigned char drive_exists; } harddisk_info_t; -#define NUM_HD (2) +#define NUM_HD (4) extern harddisk_info_t harddisk_info[NUM_HD]; diff --git a/src/lib/linuxbiosmain.c b/src/lib/linuxbiosmain.c index fbcff8d515..5850c1aa93 100644 --- a/src/lib/linuxbiosmain.c +++ b/src/lib/linuxbiosmain.c @@ -26,6 +26,10 @@ #include #include +#ifdef VIDEO_CONSOLE +#include +#endif + #include "do_inflate.h" @@ -147,11 +151,17 @@ int linuxbiosmain(unsigned long base, unsigned long totalram) set_memory_size(empty_zero_page, 0x3c00, totalram - 2048); post_code(0xfa); - printk_notice("command line - [%s]\n", cmd_line); + printk_notice("\ncommand line - [%s]\n", cmd_line); set_command_line(empty_zero_page, cmd_line); set_root_rdonly(empty_zero_page); + +#ifdef VIDEO_CONSOLE + set_display(empty_zero_page, LINES, COLS); +#else set_display(empty_zero_page, 25, 80); +#endif + set_initrd(empty_zero_page, initrd_start, initrd_size); /* Reset to booting from this image as late as possible */ diff --git a/src/lib/video_subr.c b/src/lib/video_subr.c index 7233de4b0c..ff7bfcb4b8 100644 --- a/src/lib/video_subr.c +++ b/src/lib/video_subr.c @@ -1,22 +1,50 @@ +/* + * + * modified from original freebios code + * by Steve M. Gehlbach + * + */ + #include #include +#include +#include + +void beep(int ms); -# This used to work but has not been tested recently. -// kludgy but this is only used here ... static char *vidmem; /* The video buffer, should be replaced by symbol in ldscript.ld */ -static int video_line, video_col; +int video_line, video_col; -#define LINES 25 /* Number of lines and */ -#define COLS 80 /* columns on display */ -#define VIDBUFFER 0xA000; +#define VIDBUFFER 0xB8000; + +void memsetw(void *s, int c, unsigned int n) +{ + int i; + u16 *ss = (u16 *) s; + + for (i = 0; i < n; i++) { + ss[i] = ( u16 ) c; + } +} void video_init(void) { + + // these are globals video_line = 0; video_col = 0; - vidmem = (char *) VIDBUFFER; - memset(vidmem, 0, 64*1024); + vidmem = (unsigned char *) VIDBUFFER; + + // mainboard or chip specific init routines + // also loads font + vga_hardware_fixup(); + + // set attributes, char for entire screen + // font should be previously loaded in + // device specific code (vga_hardware_fixup) + memsetw(vidmem, VGA_ATTR_CLR_WHT, 2*1024); // } + static void video_scroll(void) { int i; @@ -30,15 +58,29 @@ void video_tx_byte(unsigned char byte) { if (byte == '\n') { video_line++; - } - else if (byte == '\r') { video_col = 0; - } - else { + + } else if (byte == '\r') { + video_col = 0; + + } else if (byte == '\b') { + video_col--; + + } else if (byte == '\t') { + video_col += 4; + + } else if (byte == '\a') { + //beep + beep(500); + + } else { vidmem[((video_col + (video_line *COLS)) * 2)] = byte; - vidmem[((video_col + (video_line *COLS)) * 2) +1] = 0x07; + vidmem[((video_col + (video_line *COLS)) * 2) +1] = VGA_ATTR_CLR_WHT; video_col++; } + if (video_col < 0) { + video_col = 0; + } if (video_col >= COLS) { video_line++; video_col = 0; @@ -47,4 +89,8 @@ void video_tx_byte(unsigned char byte) video_scroll(); video_line--; } + // move the cursor + write_crtc((video_col + (video_line *COLS)) >> 8, CRTC_CURSOR_HI); + write_crtc((video_col + (video_line *COLS)) & 0x0ff, CRTC_CURSOR_LO); } + diff --git a/src/northsouthbridge/sis/630/Config b/src/northsouthbridge/sis/630/Config index 3b0365f040..c2965d33c7 100644 --- a/src/northsouthbridge/sis/630/Config +++ b/src/northsouthbridge/sis/630/Config @@ -4,3 +4,4 @@ raminit northsouthbridge/sis/630/raminit.inc object southbridge.o object northbridge.o +object sis630_vga.o VIDEO_CONSOLE diff --git a/src/northsouthbridge/sis/630/northbridge.c b/src/northsouthbridge/sis/630/northbridge.c index b271efa64c..4d2d78fb4a 100644 --- a/src/northsouthbridge/sis/630/northbridge.c +++ b/src/northsouthbridge/sis/630/northbridge.c @@ -107,7 +107,7 @@ struct mem_range *sizeram(void) mem[1].sizek = 64*1024; } mem[1].sizek -= mem[1].basek; - return &mem; + return &mem[0]; } @@ -118,7 +118,7 @@ void framebuffer_on() u16 command; if ((pcidev = pci_find_device(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_5591_AGP, NULL)) == NULL) - return 0; + return; pci_read_config_word(pcidev, 0x04, &command); command |= 0x20; diff --git a/src/northsouthbridge/sis/630/raminit.inc b/src/northsouthbridge/sis/630/raminit.inc index 15b2c24ff8..2c00a18dc5 100644 --- a/src/northsouthbridge/sis/630/raminit.inc +++ b/src/northsouthbridge/sis/630/raminit.inc @@ -34,6 +34,7 @@ #define NORTH_BRIDGE_BASE_ADDR 0x80000000 #define LPC_BRIDGE_BASE_ADDR 0x80000800 +#define PCI_PCI_BRIDGE_BASE_ADDR 0x80001000 register_setting_start: movl $northbridge_init_table, %esi @@ -63,6 +64,28 @@ write_northbridge_register: outb %al, %dx loopnz init_northbridge +#ifdef VIDEO_CONSOLE +// by S. Gehlbach < steve @ kesa . com > +// this turns on the vga io access + movw $0x3e08, %ax # Writing PCI-PCI VGA I/O enable register +write_vga_register: + /* Input: AH - register number. AL - register value. */ + movl $PCI_PCI_BRIDGE_BASE_ADDR, %edx + movl %eax, %ebx # Save %eax to %ebx. + + movzbl %bh, %eax # add register address to + addl %edx, %eax # PCI base address + + movw $PCI_COMMAND_PORT, %dx + outl %eax, %dx + + movw $PCI_DATA_PORT, %dx + andb $0x03, %al + addb %al, %dl + movb %bl, %al + outb %al, %dx +#endif + #ifdef DISABLE_INTERNAL_DEVICES movw $0x7c0e, %ax # Writting undocumented LPC register write_lpc_register: diff --git a/src/northsouthbridge/sis/630/southbridge.c b/src/northsouthbridge/sis/630/southbridge.c index 36d9fe1733..41704609f2 100644 --- a/src/northsouthbridge/sis/630/southbridge.c +++ b/src/northsouthbridge/sis/630/southbridge.c @@ -29,6 +29,8 @@ static char rcsid[] = #define IDE_BASE1 (0x1F0u) /* primary controller */ #define ASIZE(x) (sizeof(x)/sizeof((x)[0])) +extern int video_init(void); + typedef struct { u8 size; u8 regno; @@ -369,6 +371,10 @@ final_southbridge_fixup() serial_irq_fixedup(); acpi_fixup(); ide_fixup(); - - printk_debug("Southbridge fixup done for SIS 503\n"); +#ifdef VIDEO_CONSOLE + // this has to be done here due to pci not being up + // earlier and pci resources are not ready + video_init(); +#endif + printk_debug("Southbridge fixup done for SIS 603\n"); } diff --git a/src/pc80/Config b/src/pc80/Config index d21000e40f..f9a2b0929b 100644 --- a/src/pc80/Config +++ b/src/pc80/Config @@ -3,5 +3,10 @@ object mc146818rtc.o object isa-dma.o object i8259.o object udelay_timer2.o CONFIG_UDELAY_TIMER2 +object beep.o +object vga_load_regs.o VIDEO_CONSOLE +object font_8x16.o VIDEO_CONSOLE +object vga_set_mode.o VIDEO_CONSOLE +object vga_load_pcx.o VIDEO_CONSOLE dir ide diff --git a/src/rom/floppy_fill_inbuf.c b/src/rom/floppy_fill_inbuf.c index 64c8b5b23e..3082ba5799 100644 --- a/src/rom/floppy_fill_inbuf.c +++ b/src/rom/floppy_fill_inbuf.c @@ -9,6 +9,21 @@ static unsigned long offset; +/* + * ONE_TRACK is 18 sectors (18*512) which is + * really half the sectors for a track + * on a 2 head floppy. Unfortunately DISK_H1440_TRACK is defined + * in the floppy_subr.c C file and not in a header so we define + * it again here for clarity. + */ +#define DISK_H1440_SECT 18 +#define ONE_TRACK DISK_H1440_SECT*512 +static unsigned char buffer[ONE_TRACK]; +static unsigned int block_num = 0; +static unsigned int first_fill = 1; + +static byte_offset_t floppy_read_b(void *vdest, byte_offset_t offset, byte_offset_t count); + static int init_bytes(void) { offset = 0; @@ -23,7 +38,7 @@ static void fini_bytes(void) static byte_offset_t read_bytes(void *vdest, byte_offset_t count) { byte_offset_t len; - len = floppy_read(vdest, offset, count); + len = floppy_read_b(vdest, offset, count); if (len > 0) { offset += len; } @@ -42,3 +57,37 @@ static struct stream floppy_bytes __stream = { .skip = skip_bytes, .fini = fini_bytes, }; + + +static byte_offset_t floppy_read_b(void *vdest, byte_offset_t offset, byte_offset_t count) +{ + byte_offset_t bytes = 0; + unsigned char *dest = vdest; + + //printk_debug("floppy_read count = %x\n", count); + while (bytes < count) { + unsigned int byte_offset, len; + + /* The block is not cached in memory or first time called */ + if (block_num != offset / (ONE_TRACK) || first_fill) { + block_num = offset / (ONE_TRACK); + floppy_read(buffer, block_num*(ONE_TRACK), (ONE_TRACK)); + first_fill = 0; + //printk_debug("floppy_read_b dest= 0x%x offset= %d block_num= %d\n", dest, offset, block_num); + } + + byte_offset = offset % (ONE_TRACK); + len = (ONE_TRACK) - byte_offset; + if (len > (count - bytes)) { + len = (count - bytes); + } + + memcpy(dest, buffer + byte_offset, len); + + offset += len; + bytes += len; + dest += len; + + } + return bytes; +} diff --git a/src/rom/ide_fill_inbuf.c b/src/rom/ide_fill_inbuf.c index 15b5bf7c4e..6056148d63 100644 --- a/src/rom/ide_fill_inbuf.c +++ b/src/rom/ide_fill_inbuf.c @@ -16,19 +16,25 @@ extern int ide_init(void); static unsigned long offset; static int init_bytes(void) { - int i; + int i,res; printk_debug ("Trying polled ide\n"); printk_debug ("Waiting for ide disks to spin up\n"); - printk_debug ("This is a hard coded delay and longer than necessary.\n"); - for (i = 0; i < 15; i++) { - printk_debug("."); + printk_notice ("This is a hard coded delay and longer than necessary.\n"); + for (i = 0; i < 2; i++) { + printk_notice ("."); delay(1); } - printk_debug("\n"); + printk_info ("\n"); +#ifdef ONE_TRACK + offset = (ONE_TRACK*512); +#else offset = 0x7e00; - return ide_init(); +#endif + res = ide_init(); + delay(1); + return res; } static void fini_bytes(void) @@ -39,7 +45,9 @@ static void fini_bytes(void) static unsigned char buffer[512]; static unsigned int block_num = 0; static unsigned int first_fill = 1; - +#ifndef IDE_BOOT_DRIVE +#define IDE_BOOT_DRIVE 0 +#endif static byte_offset_t ide_read(void *vdest, byte_offset_t offset, byte_offset_t count) { byte_offset_t bytes = 0; @@ -54,10 +62,11 @@ static byte_offset_t ide_read(void *vdest, byte_offset_t offset, byte_offset_t c /* The block is not cached in memory or frist time called */ if (block_num != offset / 512 || first_fill) { block_num = offset / 512; - ide_read_sector(0, buffer, block_num, + printk_notice ("."); + ide_read_sector(IDE_BOOT_DRIVE, buffer, block_num, 0, 512); first_fill = 0; -#if 1 +#if 0 //printk_debug("ide_read offset = %x\n", offset); //printk_debug("ide_read block_num = %x\n", block_num); for (i = 0; i < 16; i++) {