support for new boards and chips and cpus

This commit is contained in:
Ronald G. Minnich 2002-12-16 18:03:22 +00:00
parent 14342bf376
commit 7699e7a8f9
29 changed files with 7973 additions and 0 deletions

View file

@ -0,0 +1,2 @@
object stpc_vga.o
object stpc_conf.o

View file

@ -0,0 +1,66 @@
/*
* for STPC ConsumerII
*
* by Steve M. Gehlbach
*
* mostly borrowed from st web site and converted
* to ATT ordering for gnu asm
*
* took out turning on L1 since this is done later in linuxbios main C
* code.
*/
/************************************************
* *
* Setup stpc specific cache registers *
* *
************************************************/
// smg note: linux croaks if this section of code is not run early on
stpc_chip_post_macro(0x19)
#if 0 // this is done later
// enable L1 cache (below per ST web site prim_bl)
movl %cr0, %eax
andl $~0x60000000, %eax
movl %eax, %cr0
#endif
// set cache timing for > 75Mhz
movb $0x22, %ah
stpc_conf_read_macro
andb $0b10000000, %al
orb $0b00000101, %al
stpc_conf_write_macro
// enable L1 cache write back mode
movb $0x20, %ah
stpc_conf_read_macro
orb $0b00100000, %al
stpc_conf_write_macro
#if 0 // this is done later
// enable CPU WB (cr0/nw=1)
movl %cr0, %eax
bts $29, %eax
movl %eax, %cr0
#endif
// CC2 configuration control register
// enable WB interface, burst write cycles, and lock NW
movb $0xc2, %ah
stpc_conf_read_macro
andb $~0b00100000, %al
orb $ 0b01000110, %al
stpc_conf_write_macro
// set isa timing and isa buffering
movb $0x001, %ah // ipc config register
stpc_conf_read_macro
andb $0x03, %al // clear ws bits (0 ws)
stpc_conf_write_macro
movb $0x050, %ah // misc reg0
movb $0b11010000, %al // r/w post enable, 0 WS, pciclk/4
stpc_conf_write_macro
stpc_chip_post_macro(0x20)

View file

@ -0,0 +1,238 @@
/*
* Bootstrap code for the STPC Consumer II
*
* By Steve M. Gehlbach
*
* Heavily changed; pretty much only for the ConsumerII.
*
* originally by:
* johryd
* Copyright (c) 1999 by Net Insight AB. All Rights Reserved.
*
*
*/
#include "cpu/stpc/consumer2/stpc.h"
/*
* Initialize the STPC chip based on the table
* at the end of this file.
*
* stpc_chip_init:
*/
stpc_chip_init:
/*
* Disable shadow 0xf000, since we already use
* the link register (%sp), we can't call the
* ``stpc_chip_write´´ routine.
*/
movb $0x11, %al
outb %al,$0x80
xorb %al, %al
movb $0x28, %ah
stpc_conf_write_macro
jmp .Lflush /* make sure now fetched from rom
* not shadow after soft reset */
.balign 16
.Lflush:
//
// move the table address and start the
// loop
//
movl $stpc_chip_table, %esi
.Lget: xorb %dh, %dh /* clear %dh */
/* get the port */
movb %cs:(%esi), %dl
cmpb $0xff, %dl
je .Ldone
/* add 1 to pointer */
inc %esi
/* get data and add 2 to pointer*/
movb %cs:(%esi), %ch /* get mask */
inc %esi
movb %cs:(%esi), %cl /* get data */
inc %esi
/* send index to index register */
movw %dx, %ax
outb %al, $STPC_CONF_REG_INDEX
/* read data, mask and set */
inb $STPC_CONF_REG_DATA, %al
andb %ch, %al
orb %cl, %al
movb %al, %cl
/* send data to register */
movw %dx, %ax
outb %al, $STPC_CONF_REG_INDEX
movb %cl, %al
outb %al, $STPC_CONF_REG_DATA
/* loop back */
jmp .Lget
.Ldone:
/****************************************
* *
* set chip refresh *
* set ISA refresh on *
* *
****************************************/
/*
* stpc_chip_refresh:
*/
stpc_chip_refresh:
/*
* This has been upgraded to include CONSUMER_II timings
* First of all we get the bus speed
* into the %al register
*/
xorl %eax, %eax
stpc_chip_getbusspeed_macro
movl $stpc_dram_refresh, %ebx
xorb %ah, %ah
addl %eax, %ebx // offset into the table
movb %cs:0(%ebx), %al // load refresh value
movb $0x39, %ah /* refresh control reg */
stpc_conf_write_macro
// set isa refresh on
movb $0x57, %ah
stpc_conf_read_macro //read value into %al
orb $0b00000001, %al
stpc_conf_write_macro
// make sure any coprocessor is properly reset
xorw %ax, %ax
outb %al, $0xf0
stpc_delay_macro(10)
outb %al, $0xf1
stpc_delay_macro(10)
jmp stpc_chip0
/*
* stpc_chip_table:
* format is reg addr, mask, data
* reg is first read into register
* mask is anded into register, data is ored into register
* Data to initialize the chip.
*/
stpc_chip_table:
/*
* Cache/CPU interface registers:
*/
.byte 0xC1, 0b11100000, 0b00000000 // clear no lock
.byte 0xC2, 0b00000001, 0b00000010 // enable write back
// enable BARB disable WT rom
.byte 0x20, 0b00000000, 0b00101000 // synch burst SRAM
// support L1 write-back
.byte 0x21, 0b00000001, 0b10100000 // cache size 2MB
.byte 0x22, 0b10000000, 0b01111111 // slowest timings
.byte 0x24, 0b00000000, 0b00000000 /* no ISA mem hole */
/*
* Shadow:
*/
.byte 0x25, 0b00000000, 0b00000000 /* shadow disable for C000 seg */
.byte 0x26, 0b00000000, 0b00000000 /* shadow disable for D000 seg */
.byte 0x27, 0b00000000, 0b00000000 /* shadow disable for E000 seg */
.byte 0x28, 0b00011100, 0b00000000 /* shadow disable for F000 seg , enable VGA for A0000*/
/*
* ISA interface:
*/
.byte 0x59, 0b11111110, 0b00000000 /* ISA synchronizer on */
.byte 0x50, 0b00000000, 0b00000000 /* ISA Misc 0: 14MHz/2 no post, enable kbd, a20+reset */
/*
* ROM chip select: (ISA INTERFACE, page 13/17)
*/
.byte 0x51, 0b00010000, 0b00001000 // ISA Misc 1: ROM write protect
// segments E,D,C segment share off
/*
* IPC:
*/
.byte 0x01, 0b00000000, 0b11000000 /* IPC Config: 4clk wait state on ipc */
.byte 0x52, 0b01110000, 0b00000000 // PCI IRQ A disable
.byte 0x53, 0b01110000, 0b00000000 // PCI IRQ B disable
.byte 0x54, 0b01110000, 0b00000000 // PCI IRQ C disable
.byte 0x55, 0b01110000, 0b00000000 // PCI IRQ D disable
.byte 0x56, 0b00000111, 0b00000000 /* IRQ Level: irqs 0-7 are edge sensitive */
.byte 0x57, 0b00100000, 0b00000001 /* IRQ Level: irqs 8-15 are edge sensitive, ISA refresh toggle. */
.byte 0x58, 0b01110000, 0b00000000 // VMI IRQ routing: disable
.byte 0x40, 0b10000000, 0x4b // m=9, n=166, p=3
.byte 0x41, 0b00000000, 0xa6 // f= 66 Mhz
/*
* Graphic stuff:
*/
.byte 0x29, 0b11110000, 0b00000011 /* VGA enable, PCI palette snoop disabled*/
/*
* Power managment:
* disable all
*/
.byte 0x60, 0b00000011, 0b00000000
.byte 0x61, 0b10000001, 0b00000000
.byte 0x8d, 0b00011111, 0b00000000
.byte 0x62, 0b00000001, 0b00000000
.byte 0x63, 0b11011111, 0b00000000
.byte 0x64, 0b00011111, 0b00000000
.byte 0x65, 0b00000011, 0b00000000
.byte 0x66, 0b11011111, 0b00000000
.byte 0x67, 0b00000011, 0b00000000
.byte 0x69, 0b00000011, 0b00000000
// .byte 0x68, 0b00000000, 0b00000000 // doesnt exist??
// .byte 0x6a, 0b00000000, 0b00000000 // not necessary
.byte 0x6b, 0b00000000, 0b00000000 // PMU Range00
.byte 0x6c, 0b00000000, 0b00000000 // PMU Range01
/*
* SMI generation:
*/
.byte 0x71, 0b00000001, 0b00000000 /* do not generate SMI */
/* PMU: */
.byte 0x7a, 0b10000000, 0b00000000 // PMU Status Reg
.byte 0x7c, 0b00000001, 0b00000000 /* CPU clock trottle disable,
* Clock off enable */
.byte 0xff /* end of table */
/*
*
*/
stpc_dram_refresh:
// the clock freq table from the Bios Writers Guide conflicts with that in the data sheet
// for clock speeds, so the data sheet values are used.
// empty positions are filled in with defaults at 66 Mhz
//
/* frequencies in Mhz */
/*
clock freq from BWG based on reading strap value; data sheet differs
.byte 25, 50, 60, 66, 135/2, 69, 141/2, 72, 147/2, 75, 153/2
.byte 78, 159/2, 81, 165/2, 84, 171/2, 87, 177/2, 90, 183/2, 93
.byte 189/2, 96, 195/2, 100, 105, 110, 115, 120, 125, 133
*/
.byte 25*156/(10*16), 50*156/(10*16), 60*156/(10*16), 66*156/(10*16), 0x41,0x41,0x41,0x41
.byte 0x41, 75*156/(10*16), 0x41,0x41,0x41,0x41,0x41,0x41
.byte 0x41,0x41,0x41,90*156/(10*16),0x41,0x41,0x41,0x41
.byte 0x41, 100*156/(10*16),0x41,0x41,0x41,0x41,0x41,0x41
stpc_chip0:

View file

@ -0,0 +1,20 @@
/*
* by
* Steve M. Gehlbach
*
* Read/write the special configuration registers on the STPC
*/
#include <cpu/stpc/consumer2/stpc.h>
#include <types.h>
#include <cpu/p5/io.h>
u8 stpc_conf_readb( u8 port) {
outb(port, STPC_CONF_REG_INDEX);
return inb(STPC_CONF_REG_DATA);
}
void stpc_conf_writeb( u8 data, u8 port) {
outb(port, STPC_CONF_REG_INDEX);
outb(data, STPC_CONF_REG_DATA);
}

View file

@ -0,0 +1,33 @@
/*
* originally by johryd
* modified by
* Steve M. Gehlbach
*
*/
/************************************************
* *
* Set Graphics memory (framebuffer) size *
* register (0x36). *
* This register defines the size of DRAM *
* used by graphics for frame buffer. *
* *
* Bits 0-5 (Top of Graphics Memory) indicates *
* frame buffer size in 128KB units. The range *
* is 0 to 32 for 0 to 4MB framebuffer, so 6 *
* bits are necessary. *
* *
* Note: cant change framebuffer size if *
* executing from ram since FB memory *
* is taken from bottom not top so mem *
* addresses change. *
* *
************************************************/
#if (STPC_FRAME_BUF_SZ / 128) > 33
#error "frame buffer size >= 4MB)"
#endif
movb $0x36, %ah
movb $(STPC_FRAME_BUF_SZ >> 7), %al
stpc_conf_write_macro

View file

@ -0,0 +1,158 @@
/*
* originally on ST web site
*
* converted to ATT syntax
* by
* Steve M. Gehlbach
*
*/
// Initialize basic I/O devices
movb $0x16, %al
outb %al, $0x80
stpc_io_init:
movl $IoInitTable, %ebx
IoInitLoop:
movzbw %cs:0(%ebx), %dx // get the address
cmpb $0x0ff, %dl
je IoInitEnd
incw %bx
movb %cs:0(%ebx), %al // get the value
incw %bx
outb %al, %dx // put the value in the port
jmp IoInitLoop
IoInitEnd:
jmp EnableGateA20 // keep going
IoInitTable: // I/O initialization table
// Slave PIC
.byte 0xA0, 0b00010001 // ICW1: ICW4 needed
// .byte 0xA1, 0x070 // ICW2: interrupt vector
// from linux 2.2, the st settings dont work for linux
.byte 0xA1, 0x028 // ICW2: interrupt vector
.byte 0xA1, 2 // ICW3: slave cascade
.byte 0xA1, 0b00000001 // ICW4: 8086 mode
.byte 0xA1, 0b11111111 // mask: all masked
// Master PIC
.byte 0x20, 0b00010001 // ICW1: ICW4 needed
// .byte 0x21, 0x008 // ICW2: interrupt vector
// from linux 2.2, the st settings dont work for linux
.byte 0x21, 0x020 // ICW2: interrupt vector
.byte 0x21, 1 << 2 // ICW3: master cascade
.byte 0x21, 0b00000001 // ICW4: 8086 mode
.byte 0x21, ~ (1 << 2) // mask: all masked except IRQ2
// PIT
.byte 0x43, 0b00110110 // Timer 0 (system time): mode 3
.byte 0x40, 0x0FF // 18.2Hz (1.19318MHz/65535)
.byte 0x40, 0x0FF
.byte 0x43, 0b01010100 // Timer 1 (ISA refresh): mode 2
.byte 0x41, 18 // 64KHz (1.19318MHz/18)
// Slave DMA
.byte 0x00, 0 // clear base address 0
.byte 0x00, 0
.byte 0x01, 0 // clear count 0
.byte 0x01, 0
.byte 0x02, 0 // clear base address 1
.byte 0x02, 0
.byte 0x03, 0 // clear count 1
.byte 0x03, 0
.byte 0x04, 0 // clear base address 2
.byte 0x04, 0
.byte 0x05, 0 // clear count 2
.byte 0x05, 0
.byte 0x06, 0 // clear base address 3
.byte 0x06, 0
.byte 0x07, 0 // clear count 3
.byte 0x07, 0
.byte 0x0B, 0b01000000 // set channel 0 to single mode, verify transfer
.byte 0x0B, 0b01000001 // set channel 1 to single mode, verify transfer
.byte 0x0B, 0b01000010 // set channel 2 to single mode, verify transfer
.byte 0x0B, 0b01000011 // set channel 3 to single mode, verify transfer
.byte 0x08, 0 // enable controller
// Master DMA
.byte 0xC0, 0 // clear base address 0
.byte 0xC0, 0
.byte 0xC2, 0 // clear count 0
.byte 0xC2, 0
.byte 0xC4, 0 // clear base address 1
.byte 0xC4, 0
.byte 0xC6, 0 // clear count 1
.byte 0xC6, 0
.byte 0xC8, 0 // clear base address 2
.byte 0xC8, 0
.byte 0xCA, 0 // clear count 2
.byte 0xCA, 0
.byte 0xCC, 0 // clear base address 3
.byte 0xCC, 0
.byte 0xCE, 0 // clear count 3
.byte 0xCE, 0
.byte 0xD6, 0b11000000 // set channel 0 to cascade mode
.byte 0xD6, 0b01000001 // set channel 1 to single mode, verify transfer
.byte 0xD6, 0b01000010 // set channel 2 to single mode, verify transfer
.byte 0xD6, 0b01000011 // set channel 3 to single mode, verify transfer
.byte 0xD0, 0 // enable controller
.byte 0x0E, 0 // enable DMA0 channels
.byte 0xD4, 0 // clear chain 4 mask
.byte 0xFF // end of table
//----------------------------------------------------------------------------
// Keyboard controller definitions
#define KBDC_CONTROL 0x064
#define KBDC_STATUS 0x064
#define KBDC_DATA 0x060
//----------------------------------------------------------------------------
// Gate A20 definitions
#define GATEA20_ENABLE 1
#define GATEA20_DISABLE 0
//----------------------------------------------------------------------------
// KbdcWaitIbe
// Wait for the keyboard controller ready to receive a command or a data.
// Inputs:
// none
// Outputs:
// none
// Uses:
// AL
#define KbdcWaitIbe \
\
0: \
inb $KBDC_STATUS, %al ;\
testb $0b00000010, %al ;\
jnz 0b ;\
//----------------------------------------------------------------------------
// EnableGateA20
//
// Requirements:
// Keyboard emulation enabled (reg STPC_MISC0/bit3=0).
// .globl EnableGateA20
EnableGateA20:
KbdcWaitIbe
movb $0xd1, %al
outb %al, $KBDC_CONTROL
KbdcWaitIbe
movb $1, %al
shl $1, %al // gate A20 is bit 1
orb $0xdd, %al
outb %al, $KBDC_DATA

View file

@ -0,0 +1,253 @@
/*
* ram size detection
* for STPC Consumer II
*
* by Steve M. Gehlbach
*
* follows code from st web site
*
* set ts=4 to edit
*/
#define STPC_MEM_GRAPHIC 0x36
#define STPC_GBASE 0x08000000
#define STPC_MEM_REG0 STPC_GBASE + 0x004C6000
#define STPC_MEM_REG1 STPC_GBASE + 0x004C6004
#define STPC_MEM_REG2 STPC_GBASE + 0x004C6008
#define SetStpc(Index,Value) \
mov Index, %al ;\
outb %al, $STPC_CONF_REG_INDEX ;\
mov Value, %al ;\
outb %al, $STPC_CONF_REG_DATA
/*----------------------------------------------------------------------------
DetectMemorySize
Determine the memory configuration.
Inputs:
DS: 4GB access
SDRAM only:
BL: bits 0-3: read clock delay
bit 4: '1' to enable CRTC latch
bit 5: '1' to enable GE latch
bit 6: '1' to enable host latch
bit 7: '1' for registered DIMM
Typical setting: 0x00- no latches, no registered, rd delay=0
Outputs:
EAX: top memory address
CY: if bank 0 is empty
Uses:
EAX, CX, EDI, ESI, BX
Sets frame buffer = 0
Craps on memory in various places.
Requirements:
Flat 4GB
Refresh running
Gate A20 enabled
-----------------------------------------------------------------------------*/
// Set SDRAM default configuration
.global DetectMemorySize
movb $0x17, %al
outb %al, $0x80
DetectMemorySize:
xor %ebx, %ebx // all params zero
movzbl %bl, %eax
and $0b10000000, %al // set registered DIMM per %bl
shlw $2, %ax
movb %bl, %al
andb $0b01110000, %al // set host, GE, CRTC latch per %bl
shll $18, %eax
// RCT=1 BL=3 RRW=3 PRA=3 CASlat=3
// MRSR=1 RCASLCY=3
orl $(8 + (0b111 << 4) + (3 << 8) + (3 << 15) + (3 << 19) \
+ (1 << 26) + (3 << 28) ), %eax
// TRC=8, TRCD=3, TRP=3, [4M*4]*16 (1024), CL=3,
// deassert RAS, update SDRAM, Read CL=CL
movl $STPC_MEM_REG0, %esi
movl %eax, %ds:(%esi)
movzx %bl, %eax
andb 0b00001111, %al // set read clock delay
orb 0b00010000, %al // enable 16mA
addw $4, %si // select STPC_MEM_REG1
movl %eax, %ds:(%esi)
// Clear frame buffer to test memory
movb $STPC_MEM_GRAPHIC, %ah
stpc_conf_read_macro
andb $0b11000000, %al // frame buffer=0
stpc_conf_write_macro
// DS:ESI = bank base address
// DS:EDI = bank end address
// CH = bank under test
movl $0, %esi // begin at address 0
movb $0x30, %ch // bank 0
.NextBank:
movl $(2 << 20), %edi // begin size detection at 2MB
// (smallest size in 64 bits)
// Set size in all bank registers
mov %esi, %eax
add %edi, %eax
shr $(20-8), %eax // AH = top address in MB
dec %ah // AH = bank size value
cmp $128, %ah // size > 128MB?
jae .End // yes, end the detection
mov %ch, %cl // start from current bank
.BankLoop1:
SetStpc(%cl, %ah)
incb %cl // next bank register
cmp $0x33, %cl // last bank register?
jbe .BankLoop1 // no, continue
// Check bank offset 0
movl $0x0A55AA55A, %eax // test pattern
movl %eax, %ds:(%esi) // write pattern
movl $0x0ffffffff, %ds:8(%esi) // precharge bus
cmpl %eax, %ds:(%esi) // does bank hold the pattern?
jne .BankEmpty // no, bank is empty
not %eax // revert pattern
movl %eax, %ds:4(%esi) // write pattern at address+4
movl $0x0ffffffff, %ds:12(%esi) // precharge bus
cmpl %eax, %ds:4(%esi) // is bank 64-bit wide?
je .FindBankSize // yes, don't modify setting
// Bits[63:32] test fails, consider bank empty
jmp .BankEmpty
.FindBankSize:
// Set size in all bank registers
movl %esi, %eax
addl %edi, %eax
shrl $(20-8), %eax // AH = top address in MB
decb %ah // AH = bank size value
cmpb $128, %ah // size > 128MB?
jae .PreviousSize // yes, return to previous size
movb %ch, %cl // start from current bank
.BankLoop2:
SetStpc(%cl, %ah)
incb %cl // next bank register
cmpb $0x33, %cl // last bank register?
jbe .BankLoop2 // no, continue
// Tag 2 power N offsets with the offset value
xorl %eax, %eax // start at offset 0
movl %eax, %ds:(%esi) // tag offset 0
movl %eax, %ds:4(%esi) // tag offset 4
movl $256, %eax // start 2 power N offset
.TagLoop:
movl %eax, %ds:(%eax,%esi) // tag offset
movl %eax, %ds:4(%eax,%esi) // tag offset+4
shll $1, %eax // next 2 power N
cmpl %edi, %eax // reach the end of the bank?
jb .TagLoop // no, continue
// Test the 2 power N offsets with the offset value
xorl %eax, %eax // start at offset 0
cmpl %eax, %ds:(%esi) // does offset hold the value?
jne .PreviousSize // no, return to previous size
cmpl %eax, %ds:4(%esi) // does offset+4 hold the value?
jne .PreviousSize // no, return to previous size
movl $256, %eax // start 2 power N offset
.TestLoop:
cmpl %eax, %ds:(%eax, %esi) // does offset hold the value?
jne .PreviousSize // no, return to previous size
cmpl %eax, %ds:4(%eax, %esi) // does offset+4 hold the value?
jne .PreviousSize // no, return to previous size
shll $1, %eax // next 2 power N
cmpl %edi, %eax // reach the end of the bank?
jb .TestLoop // no, continue
shll $1, %edi // next 2 power N size
jmp .FindBankSize
.PreviousSize:
shrl $21, %edi // previous 2 power N size (in MB)
shll $20, %edi
addl %edi, %esi // ESI = next bank base address
.BankEmpty:
movl %esi, %eax
shrl $(20-8), %eax // AH = top address in MB
stc // assume error
jz .End // exit if bank 0 is empty
dec %ah // AH = bank size value
// Detect the SDRAM configuration (16Mb / 2 banks, 64/128Mb / 2 banks or
// 64/128Mb / 4 banks) by testing for bank 0 the 3 modes and keep the one
// that gives the highest size.
// STPC Vega also supports 256Mb / 4 banks configuration.
cmpb $0x30, %ch // bank 0?
jne .AlreadyDetected // no, skip test
movl $STPC_MEM_REG1, %edi
orb $0b00100000, %ds:(%edi) // select 16mA for 64/128Mb config
addw $4, %di // select STPC_MEM_REG2
movb %ds:(%edi), %al // AL = current configuration
cmpb %bh, %ah // current size <= previous size?
jbe .NextConfig // yes, skip
movw %ax, %bx // save configuration and size
.NextConfig:
cmpb $2, %al // last configuration?
jae .BestConfig // yes, end detection
incb %al // next configuration
movb %al, %ds:(%edi) // set configuration
subl %esi, %esi // restart at address 0
movl $(2 << 20), %edi // begin size detection at 4MB
jmp .FindBankSize
// Set the best configuration
.BestConfig:
orb %bl, %bl // 16Mb config?
jnz .NotConfig16Mb // no, skip
andb $~0b00100000, %ds:-4(%edi) // clear 16mA for 64/128Mb config
.NotConfig16Mb:
movb %bl, %ds:(%edi)
movb %bh, %ah
movzbl %bh, %esi // restore base address
incw %si
shll $20, %esi
.AlreadyDetected:
// Set current bank size
SetStpc(%ch, %ah)
incb %ch // next bank
cmpb $0x33, %ch // last bank?
jbe .NextBank // no, continue
.End:
// at this point memsize is in %esi
DectectMemSize0:

View file

@ -0,0 +1,27 @@
/*
* STPC Consumer II ram setup
*
* by Steve M. Gehlbach
*
* borrowed from johryd and st web site code
*
*/
/****************************************
* *
* Set Memory Size to 4MB Default *
* *
* Set default memory bank size. *
* Bank 0 must be installed or it just *
* won't work. So we set bank 0 to *
* 4M and set the rest empty until *
* the actual memory size can be *
* determined. *
* *
****************************************/
movb $0x12, %al
outb %al, $0x80
movb $0x03, %al // 4 MB (4-1) Bank 0
movb $0x30, %bh /* reg 0x30: STPC_MEM_BANK0 */
stpc_set_memreg_macro // setting in %al, first reg in %bh, trashes %ah

View file

@ -0,0 +1,86 @@
/*
* $Id$
* $Source$
*
* turn on ram at memory hole
* This is needed to put irq route table in 0xf0000
* area by writing to this area later.
* Also move the gdt to low ram. See note below.
*
* by
* Steve M. Gehlbach (steve@kesa.com)
*
*/
movb $0x13, %al
outb %al, $0x80
// turn on write to ram at 0xf0000
movb $0x28, %ah // cache cntrl reg 3
stpc_conf_read_macro
orb $0b00000001, %al
stpc_conf_write_macro
////////////////////////////////////////////////////////////////
//
// We are going to move and reload the gdt, since we are
// executing from high mem. The current gdt is located
// above 1M and linux will hang unless the gdt is located <1M.
// So we move the gdt to ram in <1M area. Just under 0x90000
// is (apparently) a safe spot.
//
////////////////////////////////////////////////////////////////
#define NEW_GDT_PTR_ADDR 0x0008ff00
movl $new_gdt_ptr,%esi // source
movl $NEW_GDT_PTR_ADDR,%edi // find some ram
movl $(new_gdt_end-new_gdt_ptr), %ecx // get size
shrl $2, %ecx // divide by 4 and add 1
incl %ecx
rep
movsl
// reset the gdt addr to new spot
movl $(NEW_GDT_PTR_ADDR+6), (NEW_GDT_PTR_ADDR+2)
.align 4
// now load the new gdt
lgdt %cs:NEW_GDT_PTR_ADDR
ljmp $0x10, $new_gdt_loaded
new_gdt_loaded:
movb $0x14, %al
outb %al, $0x80
//
// turn on read cycles to ram in memory hole (0xf000)
//
movb $0x28, %ah // cache cntrl reg 3
stpc_conf_read_macro
orb $0b01000011, %al
stpc_conf_write_macro
movb $0x15, %al
outb %al, $0x80
jmp new_gdt_end
new_gdt_ptr:
.word 0x8000 // gdt limit=2048,
// 256 GDT entries
.word 0, 0 // gdt base (filled in later)
new_gdt:
.word 0, 0, 0, 0 // dummy
.word 0, 0, 0, 0 // unused
.word 0xFFFF // 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 // base address = 0
.word 0x9A00 // code read/exec
.word 0x00CF // granularity = 4096, 386
// (+5th nibble of limit)
.word 0xFFFF // 4Gb - (0x100000*0x1000 = 4Gb)
.word 0 // base address = 0
.word 0x9200 // data read/write
.word 0x00CF // granularity = 4096, 386
// (+5th nibble of limit)
new_gdt_end:

View file

@ -0,0 +1,133 @@
/*
*
* By
* Steve M. Gehlbach <steve@kesa.com>
*
* vga initialization specific for
* stpc consumerII
*
*/
#include <video_subr.h>
#include <string.h>
#include <pc80/vga.h>
#include <cpu/stpc/consumer2/vga_stpc.h>
#include <cpu/p5/io.h>
#include <subr.h>
#include <printk.h>
//#define VID_M_BUFFER 0x8800000;
#define CHAR_HEIGHT 16
#define VGA_FONT_BASE 0xa0000;
#define VGA_GRAFIX_BASE 0xa0000;
extern unsigned char fontdata_8x16[];
// screeninfo is in pc80/vga_load_regs.c and has the vga
// parameters for screen size etc. Change vga horiz,vert there.
// This is _not_ the structure used in the zero_page
// for linux init.
extern struct screeninfo vga_settings;
// prototypes
int vga_decode_var(struct screeninfo *var, struct vga_par *par);
int vga_set_regs(struct vga_par *par);
void vga_font_load(unsigned char *vidmem, unsigned char *font, int height, int num_chars);
void stpc_vga_init(void) {
int res;
struct vga_par vga_params;
// convert the general vga parameters in screeninfo structure
// to actual vga register settings
res = vga_decode_var(&vga_settings, &vga_params);
if ( res < 0 ) { post_code (0xFD); } //no error return for now
// enable access to vga registers
// STPC specific settings
outb(0x0, 0x94); // enable access to port 0x102
outb(0x01, 0x102); // enable VGA
outb(0x01, 0x3c3); // enable VGA
outb(0x28, 0x94); // disable access to port 0x102
// extended access STPC GE registers
// set seq reg 6 to 0x57 to unlock these
outb(6, SEQ_I);
outb(0x57, SEQ_D);
// write the registers
res = vga_set_regs( &vga_params );
if ( res < 0 ) { post_code(0xFE); } //no error return for now
// very important to get access to the FB
write_crtc(0x80, CRTC_GE_ENABLE); // en ext graphics AND enable access to FB
write_crtc(0x0, CRTC_DISP_YOFFS_L); //set scan offset
write_crtc(0x0, CRTC_DISP_YOFFS_H);
write_crtc(0x0, CRTC_REPAINT_C4); // high bits of CRTC counter regs
write_crtc(0x3e, CRTC_REPAINT_C1); // compatible text, b0 MUST BE 0 or reads dont work in mode 3
write_crtc(0x0, CRTC_PAGE_R0);
write_crtc(0x0, CRTC_PAGE_R1);
write_crtc(0xff, CRTC_GE_APER); // ext aperture
write_crtc(0x0, CRTC_REPAINT_C3); // Page select, Seq C4 off
write_crtc(0xff, CRTC_URGENT_START); // always urgent setting
write_crtc(0x0, CRTC_REPAINT_C0); // upper bits of CRTC regs
write_crtc (0x10, CRTC_PALLETTE_C); // set LUT on
write_crtc(0x0, CRTC_GE_GBASE); // GBASE address (default 0x800000)
}
extern void vga_set_amode(void);
extern void vga_set_gmode(void);
extern void delay(int secs);
extern void mdelay(int msecs);
extern int vga_load_pcx( char * pcx_file, int pcx_file_length);
#ifdef VGA_HARDWARE_FIXUP
void vga_hardware_fixup(void) {
unsigned char* font_mem, *vga_mem, *pcx_file;
int *file_size;
vga_mem = (u8 *) VGA_GRAFIX_BASE;
font_mem = (u8 *) VGA_FONT_BASE;
#ifdef PCX_FILE_LOCATION
pcx_file = (u8 *) PCX_FILE_LOCATION;
#else
pcx_file = (u8 *) 0xfffe0000;
#endif
file_size = (int *) pcx_file;
printk_info("Initializing stpc vga...");
post_code(0xa0);
stpc_vga_init();
#ifdef VIDEO_SHOW_LOGO
// mdelay(500);
printk_debug("Setting graphics mode...\n");
vga_set_gmode(); // set graphics mode
//
// the pcx_file is in flash at an address set
// in the config file with PCX_FILE_LOCATION
// the length of the file is at offset 0, file start at 4
//
printk_debug("pcx file at %x length %d\n",&pcx_file[4], *file_size);
vga_load_pcx( &pcx_file[4], *file_size);
delay(VIDEO_SHOW_LOGO);
#endif
vga_set_amode();
printk_debug("alpha mode set.\n");
vga_font_load(font_mem,fontdata_8x16,CHAR_HEIGHT,256);
post_code(0xa1);
}
#endif

View file

@ -0,0 +1,115 @@
#ifndef ROM_STPC_H
#define ROM_STPC_H
/*
* Bootstrap code for the STPC Consumer II
*
* by Steve M. Gehlbach
*
* orig by: johryd
*
*
*/
/*
* framebuffer size
*/
#define STPC_FRAME_BUF_SZ 512 /* size in kb, will be divided with 128 */
/*
* SIP configration registers:
*/
#define STPC_CONF_REG_INDEX 0x22
#define STPC_CONF_REG_DATA 0x23
/*
* DRAM types:
*/
#define STPC_DRAM_FPM_60 0
#define STPC_DRAM_FPM_70 1
#define STPC_DRAM_EDO_60 2
#define STPC_DRAM_EDO_70 3
#define STPC_DRAM_SDRAM 4
/*
* Macro: stpc_conf_write_macro
* Prototype: value = stpc_conf_write_macro(reg, data)
* %al %ah %al
*/
#define stpc_conf_write_macro \
xchgb %ah, %al ;\
outb %al, $STPC_CONF_REG_INDEX ;\
xchgb %ah, %al ;\
outb %al, $STPC_CONF_REG_DATA
/*
* Macro: stpc_conf_read_macro
* Prototype: value = stpc_conf_write_read(reg)
* %al %ah
*/
#define stpc_conf_read_macro \
xchgb %ah, %al ;\
outb %al, $STPC_CONF_REG_INDEX ;\
xchgb %ah, %al ;\
inb $STPC_CONF_REG_DATA, %al
/*
* Macro: stpc_chip_getbusspeed_macro
* Prototype: value = stpc_chip_getbusspeed()
* %al
* Trashed: %ah, %al
*/
#define stpc_chip_getbusspeed_macro \
movb $0x5f, %ah ;\
stpc_conf_read_macro ;\
andb $0b00111000, %al ;\
shrb $3, %al
/*
* Macro: stpc_outb_macro
* Prototype: stpc_outb_macro(value, port)
* Trashed: %al
*/
#define stpc_outb_macro(value,port) \
movb $(value), %al ;\
outb %al, $(port)
/*
* Macro: stpc_chip_post_macro
* Prototype: stpc_chip_post(value)
* Trashed: %al
*/
#define stpc_chip_post_macro(value) \
movb $(value), %al ;\
outb %al, $0x80
/*
* Macro: stpc_delay_macro
* Prototype: stpc_delay_macro(value)
* Trashed: %ecx, %al
*/
#define stpc_delay_macro(value) \
movl $value, %ecx ;\
0: inb $0x80, %al ;\
loop 0b
/*
* Sets all of the mem regs from %bh to 0x33 to
* the value in %al
* Macro: stpc_set_memreg_macro
* Prototype: stpc_set_memreg_macro
* Input: %bh: first mem reg to set (0x30-0x33)
* %al: setting for all the registers
* Trashed: %ah
*/
#define stpc_set_memreg_macro \
movb %bh, %ah ;\
0: ;\
stpc_conf_write_macro ;\
inc %ah ;\
cmpb $0x33, %ah ;\
jbe 0b
#endif /* ROM_STPC_H */

View file

@ -0,0 +1,35 @@
/*
* by
* Steve M. Gehlbach
* for stpc consumer II
*/
//
// STPC extended registers, non-standard
// must write 57h to seq reg 6 to access these
// must be done individually, not in par array
#define CRTC_REPAINT_C0 0x19
#define CRTC_REPAINT_C1 0x1A
#define CRTC_REPAINT_C2 0x1B
#define CRTC_REPAINT_C3 0x1C
#define CRTC_PAGE_R0 0x1D
#define CRTC_PAGE_R1 0x1E
#define CRTC_GE_ENABLE 0x1F
#define CRTC_GE_GBASE 0x20
#define CRTC_GE_APER 0x21
#define CRTC_REPAINT_C4 0x25
#define CRTC_REPAINT_C5 0x27
#define CRTC_PALLETTE_C 0x28
#define CRTC_URGENT_START 0x33
#define CRTC_DISP_YOFFS_L 0x34
#define CRTC_DISP_YOFFS_H 0x35
#define CRTC_GV_R 0x3B
// these are read only for STPC, no settings
#define CRTC_GCD_R 0x22
#define CRTC_AA_FF_R 0x24
#define CRTC_AI_R 0x26
// not in automatic list; has to be done manual
#define SEQ_XREG_UNLOCK 0x06

228
src/include/pc80/vga.h Normal file
View file

@ -0,0 +1,228 @@
/*
*
* modified
* by Steve M. Gehlbach <steve@kesa.com>
*
* Originally from linux/drivers/video/vga16.c by
* Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>
* Copyright 1999 Ben Pfaff <pfaffben@debian.org> and Petr Vandrovec <VANDROVE@vc.cvut.cz>
* Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm
* Based on VESA framebuffer (c) 1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
*
*/
#ifndef VGA_H_INCL
#define VGA_H_INCL 1
#include <cpu/p5/io.h>
#define u8 unsigned char
#define u16 unsigned short
#define u32 unsigned int
#define __u32 u32
#define VERROR -1
#define CHAR_HEIGHT 16
#define LINES 25
#define COLS 80
// macros for writing to vga regs
#define write_crtc(data,addr) outb(addr,CRT_IC); outb(data,CRT_DC)
#define write_att(data,addr) inb(IS1_RC); inb(0x80); outb(addr,ATT_IW); inb(0x80); outb(data,ATT_IW); inb(0x80)
#define write_seq(data,addr) outb(addr,SEQ_I); outb(data,SEQ_D)
#define write_gra(data,addr) outb(addr,GRA_I); outb(data,GRA_D)
u8 read_seq_b(u16 addr);
u8 read_gra_b(u16 addr);
u8 read_crtc_b(u16 addr);
u8 read_att_b(u16 addr);
#ifdef VGA_HARDWARE_FIXUP
void vga_hardware_fixup(void);
#else
#define vga_hardware_fixup() do{} while(0)
#endif
#define SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */
#define SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */
#define SYNC_EXT 4 /* external sync */
#define SYNC_COMP_HIGH_ACT 8 /* composite sync high active */
#define SYNC_BROADCAST 16 /* broadcast video timings */
/* vtotal = 144d/288n/576i => PAL */
/* vtotal = 121d/242n/484i => NTSC */
#define SYNC_ON_GREEN 32 /* sync on green */
#define VMODE_NONINTERLACED 0 /* non interlaced */
#define VMODE_INTERLACED 1 /* interlaced */
#define VMODE_DOUBLE 2 /* double scan */
#define VMODE_MASK 255
#define VMODE_YWRAP 256 /* ywrap instead of panning */
#define VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
#define VMODE_CONUPDATE 512 /* don't update x/yoffset */
/* VGA data register ports */
#define CRT_DC 0x3D5 /* CRT Controller Data Register - color emulation */
#define CRT_DM 0x3B5 /* CRT Controller Data Register - mono emulation */
#define ATT_R 0x3C1 /* Attribute Controller Data Read Register */
#define GRA_D 0x3CF /* Graphics Controller Data Register */
#define SEQ_D 0x3C5 /* Sequencer Data Register */
#define MIS_R 0x3CC // Misc Output Read Register
#define MIS_W 0x3C2 // Misc Output Write Register
#define IS1_RC 0x3DA /* Input Status Register 1 - color emulation */
#define IS1_RM 0x3BA /* Input Status Register 1 - mono emulation */
#define PEL_D 0x3C9 /* PEL Data Register */
#define PEL_MSK 0x3C6 /* PEL mask register */
/* EGA-specific registers */
#define GRA_E0 0x3CC /* Graphics enable processor 0 */
#define GRA_E1 0x3CA /* Graphics enable processor 1 */
/* VGA index register ports */
#define CRT_IC 0x3D4 /* CRT Controller Index - color emulation */
#define CRT_IM 0x3B4 /* CRT Controller Index - mono emulation */
#define ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */
#define GRA_I 0x3CE /* Graphics Controller Index */
#define SEQ_I 0x3C4 /* Sequencer Index */
#define PEL_IW 0x3C8 /* PEL Write Index */
#define PEL_IR 0x3C7 /* PEL Read Index */
/* standard VGA indexes max counts */
#define CRTC_C 25 /* 25 CRT Controller Registers sequentially set*/
// the remainder are not in the par array
#define ATT_C 21 /* 21 Attribute Controller Registers */
#define GRA_C 9 /* 9 Graphics Controller Registers */
#define SEQ_C 5 /* 5 Sequencer Registers */
#define MIS_C 1 /* 1 Misc Output Register */
#define CRTC_H_TOTAL 0
#define CRTC_H_DISP 1
#define CRTC_H_BLANK_START 2
#define CRTC_H_BLANK_END 3
#define CRTC_H_SYNC_START 4
#define CRTC_H_SYNC_END 5
#define CRTC_V_TOTAL 6
#define CRTC_OVERFLOW 7
#define CRTC_PRESET_ROW 8
#define CRTC_MAX_SCAN 9
#define CRTC_CURSOR_START 0x0A
#define CRTC_CURSOR_END 0x0B
#define CRTC_START_HI 0x0C
#define CRTC_START_LO 0x0D
#define CRTC_CURSOR_HI 0x0E
#define CRTC_CURSOR_LO 0x0F
#define CRTC_V_SYNC_START 0x10
#define CRTC_V_SYNC_END 0x11
#define CRTC_V_DISP_END 0x12
#define CRTC_OFFSET 0x13
#define CRTC_UNDERLINE 0x14
#define CRTC_V_BLANK_START 0x15
#define CRTC_V_BLANK_END 0x16
#define CRTC_MODE 0x17
#define CRTC_LINE_COMPARE 0x18
#define ATC_MODE 0x10
#define ATC_OVERSCAN 0x11
#define ATC_PLANE_ENABLE 0x12
#define ATC_PEL 0x13
#define ATC_COLOR_PAGE 0x14
#define SEQ_CLOCK_MODE 0x01
#define SEQ_PLANE_WRITE 0x02
#define SEQ_CHARACTER_MAP 0x03
#define SEQ_MEMORY_MODE 0x04
#define GDC_SR_VALUE 0x00
#define GDC_SR_ENABLE 0x01
#define GDC_COMPARE_VALUE 0x02
#define GDC_DATA_ROTATE 0x03
#define GDC_PLANE_READ 0x04
#define GDC_MODE 0x05
#define GDC_MISC 0x06
#define GDC_COMPARE_MASK 0x07
#define GDC_BIT_MASK 0x08
// text attributes
#define VGA_ATTR_CLR_RED 0x4
#define VGA_ATTR_CLR_GRN 0x2
#define VGA_ATTR_CLR_BLU 0x1
#define VGA_ATTR_CLR_YEL (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN)
#define VGA_ATTR_CLR_CYN (VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU)
#define VGA_ATTR_CLR_MAG (VGA_ATTR_CLR_BLU | VGA_ATTR_CLR_RED)
#define VGA_ATTR_CLR_BLK 0
#define VGA_ATTR_CLR_WHT (VGA_ATTR_CLR_RED | VGA_ATTR_CLR_GRN | VGA_ATTR_CLR_BLU)
#define VGA_ATTR_BNK 0x80
#define VGA_ATTR_ITN 0x08
/*
* vga register parameters
* these are copied to the
* registers.
*
*/
struct vga_par {
u8 crtc[CRTC_C];
u8 atc[ATT_C];
u8 gdc[GRA_C];
u8 seq[SEQ_C];
u8 misc; // the misc register, MIS_W
u8 vss;
};
/* Interpretation of offset for color fields: All offsets are from the right,
* inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
* can use the offset as right argument to <<). A pixel afterwards is a bit
* stream and is written to video memory as that unmodified. This implies
* big-endian byte order if bits_per_pixel is greater than 8.
*/
struct fb_bitfield {
__u32 offset; /* beginning of bitfield */
__u32 length; /* length of bitfield */
__u32 msb_right; /* != 0 : Most significant bit is */
/* right */
};
struct screeninfo {
__u32 xres; /* visible resolution */
__u32 yres;
__u32 xres_virtual; /* virtual resolution */
__u32 yres_virtual;
__u32 xoffset; /* offset from virtual to visible */
__u32 yoffset; /* resolution */
__u32 bits_per_pixel; /* guess what */
__u32 grayscale; /* != 0 Graylevels instead of colors */
struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; /* transparency */
__u32 nonstd; /* != 0 Non standard pixel format */
__u32 activate; /* see FB_ACTIVATE_* */
__u32 height; /* height of picture in mm */
__u32 width; /* width of picture in mm */
__u32 accel_flags; /* acceleration flags (hints) */
/* Timing: All values in pixclocks, except pixclock (of course) */
__u32 pixclock; /* pixel clock in ps (pico seconds) */
__u32 left_margin; /* time from sync to picture */
__u32 right_margin; /* time from picture to sync */
__u32 upper_margin; /* time from sync to picture */
__u32 lower_margin;
__u32 hsync_len; /* length of horizontal sync */
__u32 vsync_len; /* length of vertical sync */
__u32 sync; /* sync polarity */
__u32 vmode; /* interlaced etc */
__u32 reserved[6]; /* Reserved for future compatibility */
};
#endif

View file

@ -0,0 +1,36 @@
arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds
option VGA_HARDWARE_FIXUP=1
# I prefer 38400 for console
option TTYS0_BAUD=38400
mainboardinit superio/sis/950/setup_serial.inc
mainboardinit pc80/serial.inc
mainboardinit arch/i386/lib/console.inc
# chipinit.inc only works for flash not docmem
# sets up vga and other sis630 items
# it is a 32-bit alternate to real mode ipl.S
# must be done fairly early in the boot process
mainboardinit northsouthbridge/sis/630/chipinit.inc
mainboardinit cpu/p6/earlymtrr.inc
northsouthbridge sis/630
nsuperio sis/950 com1={1,38400} floppy=1 lpt=1 keyboard=1
option ENABLE_FIXED_AND_VARIABLE_MTRRS=1
option FINAL_MAINBOARD_FIXUP=1
option HAVE_PIRQ_TABLE=1
object mainboard.o
object irq_tables.o HAVE_PIRQ_TABLE
cpu p5
cpu p6

View file

@ -0,0 +1,15 @@
/* Table for DLL Clock Control Register (0x8c - 0x8f), these
for SiS630 and pcchips M787cl+
register values are very Mainboard specific */
# High Byte -> Register Low Byte -> Value
/*
.word 0x8c27 # set Clock DLL control register
.word 0x8d77 # 0x8c ~ 0x8f,
.word 0x8e01 # these values are very M/B
.word 0x8f07 # specific
*/
.word 0x8c78 # set Clock DLL control register
.word 0x8d8a # 0x8c ~ 0x8f,
.word 0x8e01 # these values are very M/B
.word 0x8f75 # specific

View file

@ -0,0 +1,29 @@
/* This file was generated by getpir.c, do not modify!
(but if you do, please run checkpir on it to verify)
Contains the IRQ Routing Table dumped directly from your memory , wich BIOS sets up
Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
*/
#include <arch/pirq_routing.h>
const struct irq_routing_table intel_irq_routing_table = {
PIRQ_SIGNATURE, /* u32 signature */
PIRQ_VERSION, /* u16 version */
32+16*5, /* there can be total 5 devices on the bus */
0, /* Where the interrupt router lies (bus) */
0x8, /* Where the interrupt router lies (dev) */
0, /* IRQs devoted exclusively to PCI usage */
0x1039, /* Vendor */
0x8, /* Device */
0, /* Crap (miniport) */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
0xd7, /* u8 checksum , this hase to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
{
{0,0x8, {{0x41, 0xdeb8}, {0x42, 0xdeb8}, {0x43, 0xdeb8}, {0x44, 0xdeb8}}, 0, 0},
{0,0x10, {{0x41, 0xdeb8}, {0x42, 0xdeb8}, {0x43, 0xdeb8}, {0x44, 0xdeb8}}, 0, 0},
{0,0x48, {{0x41, 0xceb8}, {0x42, 0xceb8}, {0x43, 0xceb8}, {0x44, 0xceb8}}, 0x1, 0},
{0,0x58, {{0x44, 0xceb8}, {0x41, 0xceb8}, {0x42, 0xceb8}, {0x43, 0xceb8}}, 0x2, 0},
{0,0x68, {{0x43, 0xceb8}, {0x44, 0xceb8}, {0x41, 0xceb8}, {0x42, 0xceb8}}, 0x3, 0},
}
};

View file

@ -0,0 +1,20 @@
#include <printk.h>
void
mainboard_fixup(void)
{
}
void
final_mainboard_fixup(void)
{
void final_southbridge_fixup(void);
void final_superio_fixup(void);
printk_info("PCCHIPS m787cl+...");
final_southbridge_fixup();
#ifndef USE_NEW_SUPERIO_INTERFACE
final_superio_fixup();
#endif
}

View file

@ -0,0 +1,38 @@
arch i386
mainboardinit cpu/i386/entry16.inc
mainboardinit cpu/i386/entry32.inc
ldscript cpu/i386/entry16.lds
ldscript cpu/i386/entry32.lds
mainboardinit cpu/i386/reset16.inc
ldscript cpu/i386/reset16.lds
# if you prefer 38400 for the console
option TTYS0_BAUD=38400
mainboardinit cpu/stpc/consumer2/stpc_chip.inc
mainboardinit cpu/stpc/consumer2/stpc_ram_init.inc
option SMC_BASE=0x370
option HAVE_PIRQ_TABLE=1
mainboardinit superio/SMC/fdc37b78x/setup_serial.inc
mainboardinit pc80/serial.inc
mainboardinit arch/i386/lib/console.inc
mainboardinit cpu/stpc/consumer2/stpc_ioinit.inc
mainboardinit cpu/stpc/consumer2/stpc_memsize.inc
mainboardinit cpu/stpc/consumer2/stpc_framebuffer.inc
mainboardinit cpu/stpc/consumer2/stpc_shadow_ram.inc
mainboardinit cpu/stpc/consumer2/stpc_cache.inc
option VGA_HARDWARE_FIXUP=1
northsouthbridge stpc/consumer2
nsuperio SMC/fdc37b78x com1={1,38400} floppy=1 lpt=1 keyboard=1
cpu stpc/consumer2
object mainboard.o
object irq_tables.o HAVE_PIRQ_TABLE

View file

@ -0,0 +1,40 @@
/*
Contains the IRQ Routing Table
Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
Edit the irqs and mask for the stpc.
*
*/
#include <arch/pirq_routing.h>
#include <pci.h>
//
// the values are assigned on bootup
// in mainboard.c
//
#define MASK 0xffff
#define INTA 0
#define INTB 0
#define INTC 0
#define INTD 0
const struct irq_routing_table intel_irq_routing_table = {
PIRQ_SIGNATURE, /* u32 signature */
PIRQ_VERSION, /* u16 version */
32+16*3, /* there can be total 3 devices on the bus */
0, /* Where the interrupt router lies (bus) */
PCI_DEVFN(11,0), /* Where the interrupt router lies (dev) */
MASK, /* IRQs devoted exclusively to PCI usage */
0x0, /* Vendor */
0x104a, /* Vendor */
0x020a, /* Device */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
0x00, /* u8 checksum , this has to be set to value that would give 0 after the sum of all bytes for this structure (including checksum) */
{
{0,PCI_DEVFN(0x1d,0), {{INTC, MASK}, {INTD, MASK}, {INTA, MASK}, {INTB, MASK}}, 0x1, 0},
{0,PCI_DEVFN(0x1e,0), {{INTB, MASK}, {INTC, MASK}, {INTD, MASK}, {INTA, MASK}}, 0x2, 0},
{0,PCI_DEVFN(0x1f,0), {{INTA, MASK}, {INTB, MASK}, {INTC, MASK}, {INTD, MASK}}, 0x3, 0},
}
};

View file

@ -0,0 +1,206 @@
/*
* stpc consumerII final mainboard setup
* primarily sets the irq routing
*
* many values in this file are
* hardcoded for the consumerII eval motherboard
*
* by
* Steve M. Gehlbach <steve@kesa.com>
* edit with ts=4
*
*/
#include <printk.h>
#include <cpu/p5/io.h>
#include <arch/pirq_routing.h>
#include <pci.h>
////////////////////////////////////////////////////////////////
// //
// SET LIST OF INTERRUPTS HERE BY SETTING IRQ1,2,3. //
// THE LIST MUST BE UNIQUE!!!! //
// You only need as many IRQs as boards //
// plugged in, the max is 3 boards (3 slots), //
// but all 3 must be defined and unique to avoid compile //
// errors. //
// //
////////////////////////////////////////////////////////////////
#define IRQ1 9
#define IRQ2 10
#define IRQ3 11
//
//---------------------------------------------------------------
//
#if ! (IRQ1 && IRQ2 && IRQ3)
#error "irq_tables.c: IRQ1 IRQ2 IRQ3 must be defined even if not used."
#endif
#if (IRQ1 == IRQ2)
#error "irq_tables.c: Interrupts must be unique!"
#endif
#if IRQ2 == IRQ3
#error "irq_tables.c: Interrupts must be unique!"
#endif
#if IRQ1 == IRQ3
#error "irq_tables.c: Interrupts must be unique!"
#endif
extern struct irq_routing_table intel_irq_routing_table;
extern void stpc_conf_writeb(u8 data, u8 port);
extern u8 stpc_conf_readb( u8 port);
#define CONFIG_CMD(bus,devfn, where) (0x80000000 | (bus << 16) | (devfn << 8) | (where & ~3))
#define INTERRUPT_PIN 0x3d
#define INTERRUPT_LINE 0x3c
#define BUS 0
static int pci_conf1_read_config_word(unsigned char bus, int devfn, int where, u16 * value) {
outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
*value = inw(0xCFC + (where & 2));
return 0;
}
static int pci_conf1_write_config_byte(unsigned char bus, int devfn, int where, u8 value) {
outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
outb(value, 0xCFC + (where & 3));
return 0;
}
static int pci_conf1_read_config_byte(unsigned char bus, int devfn, int where, u8 * value) {
outl(CONFIG_CMD(bus, devfn, where), 0xCF8);
*value = inb(0xCFC + (where & 3));
return 0;
}
//
// calculate the irq_tables checksum
//
int calc_checksum(struct irq_routing_table *rt) {
long i;
u8 *addr,sum2=0;
addr= (u8 *) rt;
for (i=0;i<rt->size;i++) sum2 += addr[i];
return(sum2);
}
void mainboard_fixup() {
u8 pin, devfn, irq, irq_written, stpc_reg;
u8 irq_list[] = { IRQ1, IRQ2, IRQ3 };
// pirq(slot,pin); slot[0:2] pin[0:3]
u8 pirq[3][4] = { {2,3,0,1},{1,2,3,0},{0,1,2,3}};
u16 vendor_id, mask;
int i,j;
printk_debug("stpc mainboard_fixup()\n");
mask = (1<<irq_list[0]) | (1<<irq_list[1]) | (1<<irq_list[2]);
/*
* Hardcoded for the stpc consumerII motherboard.
*
* There are 3 slots with dev # 0x1d, 0x1e, 0x1f in stpc consumer2
* The registers in stpc and the routing table are setup to route the 8259 irqs
* to the pirqa..pirqd. The consumer2 motherboard is wired as follows:
*
* INTA INTB INTC INTD
* ----------------------------
* slot 1(P8): dev=0x1d wiring: PIRQ_C PIRQ_D PIRQ_A PIRQ_B
* slot 2(P9): dev=0x1e wiring: PIRQ_B PIRQ_C PIRQ_D PIRQ_A
* slot 3(P10): dev=0x1f wiring: PIRQ_A PIRQ_B PIRQ_C PIRQ_D
*
*/
//
// search all 3 slots for a device and program the pci INTERRUPT_LINE register
// note: not needed by 2.4 but used by 2.2
// also program the stpc pirq routing registers
// and set the value in the bios-style routing table used by linux.
// When done, calculate and store the routing table checksum.
//
j=0;
for (i=0;i<3;i++) {
// i= slot# -1
// read the pin if the device exists
devfn = PCI_DEVFN(0x1d+i,0);
pci_conf1_read_config_word(BUS,devfn,0,&vendor_id);
if (vendor_id == 0xffff) continue;
pci_conf1_read_config_byte(BUS,devfn,INTERRUPT_PIN,&pin);
if (!pin) continue;
printk_debug("stpc mainboard_fixup(): found INT pin for dev 0x%x -> pin %d\n",0x1d+i,pin);
pin--; // we start at 0: pin 0-3 -> INTA-D
// get the next irq in our list
irq = irq_list[j++];
// program the pci registers
pci_conf1_write_config_byte(BUS,devfn,INTERRUPT_LINE,irq);
pci_conf1_read_config_byte(BUS,devfn,INTERRUPT_LINE,&irq_written);
printk_debug("stpc mainboard_fixup(): wrote pci INTERRUPT_LINE for dev 0x%x -> irq %d (%d)\n", PCI_SLOT(devfn),irq,irq_written);
// program the stpc config registers
// based on slot and pin.
// note that since the irq list is unique it is not possible to program
// two stpc pirq registers with the same irq. Doing this will screw up the stpc and
// cause the interrupts to not work properly.
stpc_reg = pirq[i][pin] + 0x52;
switch (irq) {
case 3:
case 4:
case 5:
case 6:
case 7:
stpc_conf_writeb(stpc_conf_readb(0x56) | (1<<(irq+3)),0x56);
printk_debug("stpc_mainboard_fixup(): wrote conf register 0x56= 0x%x;",stpc_conf_readb(0x56));
break;
case 9:
case 10:
case 11:
case 12:
stpc_conf_writeb(stpc_conf_readb(0x57) | (1<<(irq-8)),0x57);
printk_debug("stpc_mainboard_fixup(): wrote conf register 0x57= 0x%x;",stpc_conf_readb(0x57));
break;
case 14:
case 15:
stpc_conf_writeb(stpc_conf_readb(0x57) | (1<<(irq-8)),0x57);
printk_debug("stpc_mainboard_fixup(): wrote conf register 0x57= 0x%x;",stpc_conf_readb(0x57));
break;
default:
continue;
}
stpc_conf_writeb(irq|0x80,stpc_reg);
printk_debug(" conf register 0x%x= 0x%x\n",stpc_reg,stpc_conf_readb(stpc_reg));
// set the routing table
// The 0xf0 causes linux to consider the irq hard-wired and use the link value
// as the actual irq, so it does not need a router for the stpc.
// Otherwise a kernel patch would be needed to add the stpc router into arch/i386/kernel/pci-irq.c
intel_irq_routing_table.slots[i].irq[pin].link = irq | 0xf0;
intel_irq_routing_table.slots[i].irq[pin].bitmap = mask;
printk_debug("stpc_mainboard_fixup(): routing_table.slots[%d].irq[%d].link,mask = 0x%x,0x%x\n",i,pin,
intel_irq_routing_table.slots[i].irq[pin].link,
intel_irq_routing_table.slots[i].irq[pin].bitmap
);
}
//
// Now...
// set the checksum in the routing table;
//
intel_irq_routing_table.checksum = 0;
intel_irq_routing_table.checksum = -calc_checksum( (struct irq_routing_table *) &intel_irq_routing_table);
printk_debug("stpc mainboard_fixup(): checksum calculated= 0x%x\n",intel_irq_routing_table.checksum);
printk_debug("stpc mainboard_fixup complete.\n");
}
void keyboard_on (void) {
return;
}

31
src/pc80/beep.c Normal file
View file

@ -0,0 +1,31 @@
#include <cpu/p5/io.h>
#include <delay.h>
static void
beep_on(void)
{
/* Timer 2, Mode 3, perodic square ware */
outb(0xb6, 0x43);
/* frequence = 440 Hz */
outb(0x97, 0x42);
outb(0x0a, 0x42);
/* Enable PC speaker gate */
outb(0x03, 0x61);
}
static void
beep_off(void)
{
/* Disable PC speaker gate */
outb_p(0x00, 0x61);
}
void beep(int ms) {
beep_on();
// delay
mdelay(ms);
beep_off();
}

4693
src/pc80/font_8x16.c Normal file

File diff suppressed because it is too large Load diff

223
src/pc80/vga_load_pcx.c Normal file
View file

@ -0,0 +1,223 @@
/***********************************************************
*
* $Id$
* $Source$
*
* load a splash image from a pcx file
* the pcs file is stored in flash at a know address.
* VGA must be in gmode prior to entering this routine.
* There are some assumptions made about the pcx image
* and the color table. See the code.
*
* by
* Steve M. Gehlbach <steve@kesa.com>
*
* pcx row decode function modified from the netpbm project
* http://download.sourceforge.net/netpbm/
*
***********************************************************/
#include <pc80/vga.h>
#include <printk.h>
#define SET_PLANE(x) write_seq(x,SEQ_PLANE_WRITE);
#define VGA_GRAFIX_BASE 0xa0000
u8 *vga = (u8 *) VGA_GRAFIX_BASE;
#define PCX_256_COLORS 0x0c
// prototypes
static void GetPCXRow(unsigned char * pcx_file, unsigned char * const pcxrow, int const bytesperline, int * file_index);
void writeVga(u8 *pcxrow);
static int rowsRead = 0;
static int xsize = 0;
static int ysize = 0;
struct pcx_header {
u8 manufacturer;
u8 version;
u8 encoding;
u8 bits_per_pixel;
u16 xmin; u16 ymin; u16 xmax; u16 ymax;
u16 HDpi;
u16 VDpi;
struct color {u8 red;
u8 blue;
u8 green;
} colormap[16];
u8 reserved;
u8 nplanes;
u16 bytes_per_line;
u16 palette_info;
u16 HscreenSize;
u16 VscreenSize;
u8 filler[54];
};
int vga_load_pcx (char * pcx_file, int size) {
int total_bytes_per_line,file_index,row,i;
u8 vgarow[650];
struct pcx_header *pcx;
pcx = (struct pcx_header *) pcx_file;
if ( ! (pcx->manufacturer == 0x0a && pcx->version == 0x05 && pcx->encoding == 0x01) ) {
printk_info("vga_load_pcx: not a compatible .pcx file.\n");
return -1;
}
if (pcx->bits_per_pixel != 8 || pcx->nplanes != 1) {
printk_info("vga_load_pcx: not a 1 plane 8-bits per pixel .pcx file. planes= %d; bits-per-pixel= %d\n",
pcx->nplanes,pcx->bits_per_pixel);
return -1;
}
xsize= pcx->xmax - pcx->xmin + 1;
ysize= pcx->ymax - pcx->ymin + 1;
total_bytes_per_line = pcx->nplanes * pcx->bytes_per_line;
printk_debug("vga_load_pcx: bits_per_pixel= %d \n xmin= %d, xmax= %d, ymin= %d, \
ymax= %d\n bytes_per_line= %d nplanes= %d\n image size (bytes)= %d\n",
pcx->bits_per_pixel,
pcx->xmin,
pcx->xmax,
pcx->ymin,
pcx->ymax,
pcx->bytes_per_line,
pcx->nplanes,
total_bytes_per_line*ysize
);
// read the color table at the end of the file
// skip first 240 colors
// we only use last 16 colors
file_index = size-769;
if (pcx_file[file_index++] != PCX_256_COLORS) {
printk_info("vga_load_pcx: invalid color table signature at file_index %d: 0x%x\n",
file_index-1,pcx_file[file_index-1]);
return -1;
}
file_index += 240*3;
i = 0;
outb_p(240, PEL_IW);
do {
// put the 16 3-tuple color table at the top of the PEL
// scale 0-255 -> 0-63
outb_p(pcx_file[file_index++]>>2, PEL_D);
outb_p(pcx_file[file_index++]>>2, PEL_D);
outb_p(pcx_file[file_index++]>>2, PEL_D);
i++;
} while ( (i < 16) && (file_index < (size-2)) );
if (i < 16)
printk_info("vga_load_pcx: Seek past end of file in loading colortable. Only %d colors loaded. file_index= %d size= %d\n",i,file_index,size);
else
printk_debug("vga_load_pcx: %d colors read into colortable.\n",i);
// set the color select to set b7-4 to 1111 to use high end of PEL
write_att(read_att_b(ATC_MODE)|0x80,ATC_MODE);
write_att(0x0f,ATC_COLOR_PAGE);
// go through the pcx file and put it into one row of 1 byte per pixel
// then call the write VGA routine to write this to vga memory
// do this for all rows up to ysize
file_index = 128;
// now get the image data and put into vga memory
for( row = 0; row < ysize; row++ ) {
GetPCXRow(pcx_file,vgarow,pcx->bytes_per_line, &file_index);
//printk_debug("Row %d complete; at pcx_file[%d].\n",rowsRead, file_index);
writeVga(vgarow);
}
printk_debug("Row %d complete; at pcx_file[%d].\n",rowsRead, file_index);
// turn on display, disable access to attr palette
inb(IS1_RC);
outb(0x20, ATT_IW);
return 0;
}
// decode pcx format
/*
* from netpbm
* read a single encoded row, handles encoding across rows
* run length encoding per http://www.whisqu.se/per/docs/graphics57.htm
*
*/
static void
GetPCXRow(unsigned char * pcx_file, unsigned char * const pcxrow,
int const bytesperline, int * file_index) {
/*----------------------------------------------------------------------------
* Read one row from the PCX raster.
*
* The PCX raster is run length encoded as follows: If the upper two
* bits of a byte are 11, the lower 6 bits are a repetition count for the
* raster byte that follows. If the upper two bits are not 11, the byte
* _is_ a raster byte, with repetition count 1.
*
* A run can't span rows, but it can span planes within a row. That's
* why 'repetitionsLeft' and 'c' are static variables in this
* subroutine.
*-----------------------------------------------------------------------------*/
static int repetitionsLeft = 0;
static int c;
int bytesGenerated;
bytesGenerated = 0;
while( bytesGenerated < bytesperline ) {
if(repetitionsLeft > 0) {
pcxrow[bytesGenerated++] = c;
--repetitionsLeft;
} else {
c = pcx_file[(*file_index)++];
if ((c & 0xc0) != 0xc0)
/* This is a 1-shot byte, not a repetition count */
pcxrow[bytesGenerated++] = c;
else {
/* This is a repetition count for the following byte */
repetitionsLeft = c & 0x3f;
c = pcx_file[(*file_index)++];
}
}
}
rowsRead++;
}
/*---------------------------------------------------------------------------------
* write one row of the vga raster to the memory
* the vga memory is 1 bit per pixel and the pcxrow
* is 1 pixel per byte. The vga memory is organized
* into planes for each bit (4 planes).
*
*--------------------------------------------------------------------------------*/
void writeVga(u8 *pcxrow) {
int i, j, offset;
u8 pixel[4] = {0,0,0,0};
u8 mask, s_pixel;
// offset is less one since we process 8 bytes
// before writing the first vga byte. This way we
// don't have to subtract one in the loop below.
offset = (rowsRead-1) * (xsize>>3) - 1;
for (i=0;i<=xsize;i++) {
if ( (i != 0) && (i % 8 == 0)) {
// write each plane
for (j=0;j<4;j++) {
// set plane j
SET_PLANE(1<<j);
// write byte to plane
vga[ ( i>>3 ) + offset] = pixel[j];
// clear the value
pixel[j] = 0;
}
if (i >= xsize) return;
}
// pixel value is at high end so subtract 240
s_pixel = pcxrow[i] - 240;
mask = 0x80 >> (i % 8);
for (j=0;j<4;j++)
if (s_pixel & (1<<j) )
pixel[j] |= mask;
else
continue;
}
}

419
src/pc80/vga_load_regs.c Normal file
View file

@ -0,0 +1,419 @@
#include <video_subr.h>
#include <string.h>
#include <pc80/vga.h>
#include <cpu/p5/io.h>
/*
* $Id$
* $Source$
*
* from the Linux kernel code base.
* orig by Ben Pfaff and Petr Vandrovec.
*
* modified by
* Steve M. Gehlbach <steve@kesa.com>
*
* NOTE: to change the horiz and vertical pixels,
* change the xres,yres,xres_virt,yres_virt setting
* in the screeninfo structure below. You may also need
* to change the border settings as well.
*
* Convert the screeninfo structure to data for
* writing to the vga registers
*
*/
// prototypes
int vga_decode_var(struct screeninfo *var, struct vga_par *par);
int vga_set_regs(struct vga_par *par);
extern u8 VgaLookupTable[];
u8 read_seq_b(u16 addr) {
outb(addr,SEQ_I);
return inb(SEQ_D);
}
u8 read_gra_b(u16 addr) {
outb(addr,GRA_I);
return inb(GRA_D);
}
u8 read_crtc_b(u16 addr) {
outb(addr,CRT_IC);
return inb(CRT_DC);
}
u8 read_att_b(u16 addr) {
inb(IS1_RC);
inb(0x80);
outb(addr,ATT_IW);
return inb(ATT_R);
}
/*
From: The Frame Buffer Device
by Geert Uytterhoeven <geert@linux-m68k.org>
in the linux kernel docs.
The following picture summarizes all timings. The horizontal retrace time is
the sum of the left margin, the right margin and the hsync length, while the
vertical retrace time is the sum of the upper margin, the lower margin and the
vsync length.
+----------+---------------------------------------------+----------+-------+
| | ^ | | |
| | |upper_margin | | |
| | | | | |
+----------###############################################----------+-------+
| # ^ # | |
| # | # | |
| # | # | |
| # | # | |
| left # | # right | hsync |
| margin # | xres # margin | len |
|<-------->#<---------------+--------------------------->#<-------->|<----->|
| # | # | |
| # | # | |
| # | # | |
| # |yres # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
| # | # | |
+----------###############################################----------+-------+
| | ^ | | |
| | |lower_margin | | |
| | | | | |
+----------+---------------------------------------------+----------+-------+
| | ^ | | |
| | |vsync_len | | |
| | | | | |
+----------+---------------------------------------------+----------+-------+
All horizontal timings are in number of dotclocks
(in picoseconds, 1E-12 s), and vertical timings in number of scanlines.
The vga uses the following fields:
- pixclock: pixel clock in ps (pico seconds)
- xres,yres,xres_v,yres_v
- left_margin: time from sync to picture
- right_margin: time from picture to sync
- upper_margin: time from sync to picture
- lower_margin: time from picture to sync
- hsync_len: length of horizontal sync
- vsync_len: length of vertical sync
*/
/* our display parameters per the above */
struct screeninfo vga_settings = {
640,400,640,400,/* xres,yres,xres_virt,yres_virt */
0,0, /* xoffset,yoffset */
4, /* bits_per_pixel NOT USED*/
0, /* greyscale ? */
{0,0,0}, /* R */
{0,0,0}, /* G */
{0,0,0}, /* B */
{0,0,0}, /* transparency */
0, /* standard pixel format */
0, // activate now
-1,-1, // height and width in mm
0, // accel flags
39721, // pixclock: 79442 -> 12.587 Mhz (NOT USED)
// 70616 -> 14.161
// 39721 -> 25.175
// 35308 -> 28.322
48, 16, 39, 8, // margins left,right,upper,lower
96, // hsync length
2, // vsync length
0, // sync polarity
0, // non interlaced, single mode
{0,0,0,0,0,0} // compatibility
};
// ALPHA-MODE
// Hard coded to BIOS VGA mode 3 (alpha color text)
// screen size settable in screeninfo structure
int vga_decode_var(struct screeninfo *var,
struct vga_par *par)
{
u8 VgaAttributeTable[16] =
{ 0x000, 0x001, 0x002, 0x003, 0x004, 0x005, 0x014, 0x007, 0x038, 0x039, 0x03A, 0x03B, 0x03C, 0x03D, 0x03E, 0x03F};
u32 xres, right, hslen, left, xtotal;
u32 yres, lower, vslen, upper, ytotal;
u32 vxres, xoffset, vyres, yoffset;
u32 pos;
u8 r7, rMode;
int i;
xres = (var->xres + 7) & ~7;
vxres = (var->xres_virtual + 0xF) & ~0xF;
xoffset = (var->xoffset + 7) & ~7;
left = (var->left_margin + 7) & ~7;
right = (var->right_margin + 7) & ~7;
hslen = (var->hsync_len + 7) & ~7;
if (vxres < xres)
vxres = xres;
if (xres + xoffset > vxres)
xoffset = vxres - xres;
xres >>= 3;
right >>= 3;
hslen >>= 3;
left >>= 3;
vxres >>= 3;
xtotal = xres + right + hslen + left;
if (xtotal >= 256)
return VERROR; //xtotal too big
if (hslen > 32)
return VERROR; //hslen too big
if (right + hslen + left > 64)
return VERROR; //hblank too big
par->crtc[CRTC_H_TOTAL] = xtotal - 5;
par->crtc[CRTC_H_BLANK_START] = xres - 1;
par->crtc[CRTC_H_DISP] = xres - 1;
pos = xres + right;
par->crtc[CRTC_H_SYNC_START] = pos;
pos += hslen;
par->crtc[CRTC_H_SYNC_END] = (pos & 0x1F) | 0x20 ; //<--- stpc text mode p178
pos += left - 2; /* blank_end + 2 <= total + 5 */
par->crtc[CRTC_H_BLANK_END] = (pos & 0x1F) | 0x80;
if (pos & 0x20)
par->crtc[CRTC_H_SYNC_END] |= 0x80;
yres = var->yres;
lower = var->lower_margin;
vslen = var->vsync_len;
upper = var->upper_margin;
vyres = var->yres_virtual;
yoffset = var->yoffset;
if (yres > vyres)
vyres = yres;
if (vxres * vyres > 65536) {
vyres = 65536 / vxres;
if (vyres < yres)
return VERROR; // out of memory
}
if (yoffset + yres > vyres)
yoffset = vyres - yres;
if (var->vmode & VMODE_DOUBLE) {
yres <<= 1;
lower <<= 1;
vslen <<= 1;
upper <<= 1;
}
ytotal = yres + lower + vslen + upper;
if (ytotal > 1024) {
ytotal >>= 1;
yres >>= 1;
lower >>= 1;
vslen >>= 1;
upper >>= 1;
rMode = 0x04;
} else
rMode = 0x00;
if (ytotal > 1024)
return VERROR; //ytotal too big
if (vslen > 16)
return VERROR; //vslen too big
par->crtc[CRTC_V_TOTAL] = ytotal - 2;
r7 = 0x10; /* disable linecompare */
if (ytotal & 0x100) r7 |= 0x01;
if (ytotal & 0x200) r7 |= 0x20;
par->crtc[CRTC_PRESET_ROW] = 0;
// GMODE <--> ALPHA-MODE
// default using alpha mode so we need to set char rows= CHAR_HEIGHT-1
par->crtc[CRTC_MAX_SCAN] = 0x40 | (CHAR_HEIGHT-1); /* 16 scanlines, linecmp max*/
if (var->vmode & VMODE_DOUBLE)
par->crtc[CRTC_MAX_SCAN] |= 0x80;
par->crtc[CRTC_CURSOR_START] = 0x00; // curs enabled, start line = 0
par->crtc[CRTC_CURSOR_END] = CHAR_HEIGHT-1; // end line = 12
pos = yoffset * vxres + (xoffset >> 3);
par->crtc[CRTC_START_HI] = pos >> 8;
par->crtc[CRTC_START_LO] = pos & 0xFF;
par->crtc[CRTC_CURSOR_HI] = 0x00;
par->crtc[CRTC_CURSOR_LO] = 0x00;
pos = yres - 1;
par->crtc[CRTC_V_DISP_END] = pos & 0xFF;
par->crtc[CRTC_V_BLANK_START] = pos & 0xFF;
if (pos & 0x100)
r7 |= 0x0A; /* 0x02 -> DISP_END, 0x08 -> BLANK_START */
if (pos & 0x200) {
r7 |= 0x40; /* 0x40 -> DISP_END */
par->crtc[CRTC_MAX_SCAN] |= 0x20; /* BLANK_START */
}
pos += lower;
par->crtc[CRTC_V_SYNC_START] = pos & 0xFF;
if (pos & 0x100)
r7 |= 0x04;
if (pos & 0x200)
r7 |= 0x80;
pos += vslen;
par->crtc[CRTC_V_SYNC_END] = (pos & 0x0F) & ~0x10; /* disabled reg write prot, IRQ */
pos += upper - 1; /* blank_end + 1 <= ytotal + 2 */
par->crtc[CRTC_V_BLANK_END] = pos & 0xFF; /* 0x7F for original VGA,
but some SVGA chips requires all 8 bits to set */
if (vxres >= 512)
return VERROR; //vxres too long
par->crtc[CRTC_OFFSET] = vxres >> 1;
// put the underline off of the character, necessary in alpha color mode
par->crtc[CRTC_UNDERLINE] = 0x1f;
par->crtc[CRTC_MODE] = rMode | 0xA3; // word mode
par->crtc[CRTC_LINE_COMPARE] = 0xFF;
par->crtc[CRTC_OVERFLOW] = r7;
// not used ??
par->vss = 0x00; /* 3DA */
for (i = 0x00; i < 0x10; i++) {
par->atc[i] = VgaAttributeTable[i];
}
// GMODE <--> ALPHA-MODE
par->atc[ATC_MODE] = 0x0c; // text mode
par->atc[ATC_OVERSCAN] = 0x00; // no border
par->atc[ATC_PLANE_ENABLE] = 0x0F;
par->atc[ATC_PEL] = xoffset & 7;
par->atc[ATC_COLOR_PAGE] = 0x00;
par->misc = 0x67; /* enable CPU, ports 0x3Dx, positive sync*/
if (var->sync & SYNC_HOR_HIGH_ACT)
par->misc &= ~0x40;
if (var->sync & SYNC_VERT_HIGH_ACT)
par->misc &= ~0x80;
par->seq[SEQ_CLOCK_MODE] = 0x01; //8-bit char; 0x01=alpha mode
par->seq[SEQ_PLANE_WRITE] = 0x03; // just char/attr plane
par->seq[SEQ_CHARACTER_MAP] = 0x00;
par->seq[SEQ_MEMORY_MODE] = 0x02; // A/G bit not used in stpc; O/E on, C4 off
par->gdc[GDC_SR_VALUE] = 0x00;
// bits set in the SR_EN regs will enable set/reset action
// based on the bit settings in the SR_VAL register
par->gdc[GDC_SR_ENABLE] = 0x00;
par->gdc[GDC_COMPARE_VALUE] = 0x00;
par->gdc[GDC_DATA_ROTATE] = 0x00;
par->gdc[GDC_PLANE_READ] = 0;
par->gdc[GDC_MODE] = 0x10; //Okay
// GMODE <--> ALPHA-MMODE
par->gdc[GDC_MISC] = 0x0e; // b0=0 ->alpha mode; memory at 0xb8000
par->gdc[GDC_COMPARE_MASK] = 0x00;
par->gdc[GDC_BIT_MASK] = 0xFF;
return 0;
}
/*
* From the Linux kernel.
* orig by Ben Pfaff and Petr Vandrovec.
* see the note in the vga.h for attribution.
*
* modified by
* Steve M. Gehlbach <steve@kesa.com>
* for the linuxbios project
*
* Write the data in the vga parameter structure
* to the vga registers, along with other default
* settings.
*
*/
int vga_set_regs(struct vga_par *par)
{
int i;
/* update misc output register */
outb(par->misc, MIS_W);
/* synchronous reset on */
outb(0x00, SEQ_I);
outb(0x00, SEQ_D);
/* write sequencer registers */
outb(1, SEQ_I);
outb(par->seq[1] | 0x20, SEQ_D); // blank display
for (i = 2; i < SEQ_C; i++) {
outb(i, SEQ_I);
outb(par->seq[i], SEQ_D);
}
/* synchronous reset off */
outb(0x00, SEQ_I);
outb(0x03, SEQ_D);
/* deprotect CRT registers 0-7 */
outb(0x11, CRT_IC);
outb(par->crtc[0x11], CRT_DC);
/* write CRT registers */
for (i = 0; i < CRTC_C; i++) {
outb(i, CRT_IC);
outb(par->crtc[i], CRT_DC);
}
/* write graphics controller registers */
for (i = 0; i < GRA_C; i++) {
outb(i, GRA_I);
outb(par->gdc[i], GRA_D);
}
/* write attribute controller registers */
for (i = 0; i < ATT_C; i++) {
inb(IS1_RC); /* reset flip-flop */
inb(0x80); //delay
outb(i, ATT_IW);
inb(0x80); //delay
outb(par->atc[i], ATT_IW);
inb(0x80); //delay
}
// initialize the color table
outb(0, PEL_IW);
i = 0;
// length is a magic number right now
while ( i < (0x3f*3 + 3) ) {
outb(VgaLookupTable[i++], PEL_D);
outb(VgaLookupTable[i++], PEL_D);
outb(VgaLookupTable[i++], PEL_D);
}
outb(0x0ff, PEL_MSK); // palette mask
// very important
// turn on video, disable palette access
inb(IS1_RC); /* reset flip-flop */
inb(0x80); //delay
outb(0x20, ATT_IW);
/* Wait for screen to stabilize. */
for(i=0;i<1000;i++) { inb(0x80); }
outb(0x01, SEQ_I); // unblank display
outb(par->seq[1], SEQ_D);
// turn on display, disable access to attr palette
inb(IS1_RC);
outb(0x20, ATT_IW);
return 0;
}

149
src/pc80/vga_set_mode.c Normal file
View file

@ -0,0 +1,149 @@
/*
* $Id$
* $Source$
*
* by
* Steve M. Gehlbach <steve@kesa.com>
*
* These routines set graphics mode and alpha mode
* for switching back and forth.
*
* Register settings are
* more or less as follows:
*
* Register Graphics Alpha
* 16 color
* ------------------------------------------------
* GDC_MODE 0x00 0x10
* GDC_MISC 0x05 0x0e
* SEQ_MEMORY_MODE 0x06 0x02
* SEQ_PLANE_WRITE 0x0f 0x03
* CRTC_CURSOR_START 0x20 0x00
* CRTC_CURSOR_END 0x00 CHAR_HEIGHT-1
* CRTC_MODE 0xe3 0xa3
* CRTC_MAX_SCAN 0x40 0x40 | CHAR_HEIGHT-1
* ATC_MODE 0x01 0x0c
*
*/
#include <pc80/vga.h>
#include <printk.h>
void vga_set_gmode (void) {
u8 byte;
byte = read_att_b(ATC_MODE) & ~0x0f;
write_att(byte|0x1, ATC_MODE);
//
// display is off at this point
byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf;
write_seq(byte|0xf,SEQ_PLANE_WRITE); // all planes
byte = read_seq_b(SEQ_MEMORY_MODE);
write_seq(byte|4,SEQ_MEMORY_MODE);
byte = read_gra_b(GDC_MODE) & ~0x10;
write_gra(byte,GDC_MODE);
write_gra(0x05, GDC_MISC);
write_crtc(0x20, CRTC_CURSOR_START);
write_crtc(0x00, CRTC_CURSOR_END);
byte = read_crtc_b(CRTC_MODE) & ~0xe0;
write_crtc(byte|0xe0, CRTC_MODE);
byte = read_crtc_b(CRTC_MAX_SCAN) & ~0x01f;
write_crtc(byte, CRTC_MAX_SCAN);
byte = inb(MIS_R); // get 3c2 value by reading 3cc
outb(byte & ~0xc,MIS_W); // clear last bits to set 25Mhz clock and low page
// turn on display, disable access to attr palette
inb(IS1_RC);
outb(0x20, ATT_IW);
}
void vga_set_amode (void) {
u8 byte;
write_att(0x0c, ATC_MODE);
//reset palette to normal in the case it was changed
write_att(0x0, ATC_COLOR_PAGE);
//
// display is off at this point
write_seq(0x3,SEQ_PLANE_WRITE); // planes 0 & 1
byte = read_seq_b(SEQ_MEMORY_MODE) & ~0x04;
write_seq(byte,SEQ_MEMORY_MODE);
byte = read_gra_b(GDC_MODE) & ~0x60;
write_gra(byte|0x10,GDC_MODE);
write_gra(0x0e, GDC_MISC);
write_crtc(0x00, CRTC_CURSOR_START);
write_crtc(CHAR_HEIGHT-1, CRTC_CURSOR_END);
byte = read_crtc_b(CRTC_MODE) & ~0xe0;
write_crtc(byte|0xa0, CRTC_MODE);
byte = read_crtc_b(CRTC_MAX_SCAN) & ~0x01f;
write_crtc(byte | (CHAR_HEIGHT-1), CRTC_MAX_SCAN);
// turn on display, disable access to attr palette
inb(IS1_RC);
outb(0x20, ATT_IW);
}
/*
* by Steve M. Gehlbach, Ph.D. <steve@kesa.com>
*
* vga_font_load loads a font into font memory. It
* assumes alpha mode has been set.
*
* The font load code follows technique used
* in the tiara project, which came from
* the Universal Talkware Boot Loader,
* http://www.talkware.net.
*/
extern unsigned char fontdata_8x16[];
void vga_font_load(unsigned char *vidmem, unsigned char *font, int height, int num_chars) {
/* Note: the font table is 'height' long but the font storage area
* is 32 bytes long.
*/
int i,j;
u8 byte;
// set sequencer map 2, odd/even off
byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf;
write_seq(byte|4,SEQ_PLANE_WRITE);
byte = read_seq_b(SEQ_MEMORY_MODE);
write_seq(byte|4,SEQ_MEMORY_MODE);
// select graphics map 2, odd/even off, map starts at 0xa0000
write_gra(2,GDC_PLANE_READ);
byte = read_gra_b(GDC_MODE) & ~0x10;
write_gra(byte,GDC_MODE);
write_gra(0,GDC_MISC);
for (i = 0 ; i < num_chars ; i++) {
for (j = 0 ; j < height ; j++) {
vidmem[i*32+j] = fontdata_8x16[i*16+j];
}
}
// set sequencer back to maps 0,1, odd/even on
byte = read_seq_b(SEQ_PLANE_WRITE) & ~0xf;
write_seq(byte|3,SEQ_PLANE_WRITE);
byte = read_seq_b(SEQ_MEMORY_MODE) & ~0x4;
write_seq(byte,SEQ_MEMORY_MODE);
// select graphics back to map 0,1, odd/even on
write_gra(0,GDC_PLANE_READ);
byte = read_gra_b(GDC_MODE);
write_gra(byte|0x10,GDC_MODE);
write_gra(0xe,GDC_MISC);
}

View file

@ -0,0 +1,193 @@
/*
* Modified
* By Steve M. Gehlbach
*
* Heavily borrowed from sample code at ST web site
*
*/
//
// This is 32-bit code
// We go ahead and jam the whole chip not just the serial; it's just as easy.
//
/* The base address is either 0x3F0 or 0x370, depending on config pin */
#ifndef SMC_BASE
#error SMC_BASE must be defined as 0x3F0 or 0x370
#endif
#if (SMC_BASE == 0x370)
/* #warning SMC_BASE set to 0x370 */
#elif (SMC_BASE == 0x3f0)
/* #warning SMC_BASE set to 0x3f0 */
#else
#error SMC_BASE defined as other than 0x3F0 or 0x370
#endif
#define SMC_INDEX SMC_BASE
#define SMC_DATA SMC_BASE+1
//#define SIO_ADDR 0x370
#define SIO_ADDR SMC_BASE
#define SIO_GPIO_ADDR 0x0EA
#define SIO_GPIO_DATA 0x0EB
#define UnlockSio \
movw $SIO_ADDR, %dx ;\
movb $0x55, %al ;\
outb %al, %dx
#define LockSio \
movw $SIO_ADDR, %dx ;\
movb $0xaa, %al ;\
outb %al, %dx
#define GetSio(Index) \
movw $SIO_ADDR, %dx ;\
movb Index, %al ;\
outb %al, %dx ;\
incw %dx ;\
inb %dx, %al
#define SetSio(Index, Value) \
movw $SIO_ADDR, %dx ;\
movb Index, %al ;\
outb %al, %dx ;\
incw %dx ;\
movb Value, %al ;\
outb %al, %dx
#define SelectSioDev(Device) \
SetSio(7, Device)
//
//----------------------------------------------------------------------------
// this sets up the super IO chip
GLOBAL(stpc_board_init)
mov $0x0209, %dx // clear watchdog
xorb %al, %al
outb %al, %dx
UnlockSio
movl $SioTable, %ebx
0: SetSio( (%ebx), 1(%ebx) )
addl $2, %ebx
cmpl $SioTableEnd, %ebx
jb 0b
LockSio
// GPIO 1
// bit7: unused
// bit6: unused
// bit5: DDC line: 0=disabled, 1=enabled
// bit4: video YUV: 0=SAA, 1=VIP connector
// bit3: unused
// bit2; unused
// bit1: external 27MHz: 0=enabled, 1=disabled
// bit0: unused
movb $1, %al
outb %al, $SIO_GPIO_ADDR
movb $0b00000010, %al
outb %al, $SIO_GPIO_DATA
// return
jmp stpc_superio0
//----------------------------------------------------------------------------
// Board data
SioTable:
.byte 0x002, 0x001 // do a soft reset
.byte 0x003, 0x083 // gpio port enable (EAh/EBh)
.byte 0x022, 0x039 // power on
.byte 0x023, 0x000 // intelligent pwr mgnt off (smg: uncommented)
.byte 0x024, 0x084 // OSC is on, IRQ8 active low
// FDC
.byte 0x007, 0x000 // select
.byte 0x060, 0x003
.byte 0x061, 0x0F0 // I/O 3F0h
.byte 0x070, 0x006 // IRQ 6
.byte 0x074, 0x002 // DMA 2
.byte 0x0F0, 0x04E // FDC output push-pull
.byte 0x0F1, 0x000 // FDD option register
.byte 0x0F2, 0x0FF // FDD type register
.byte 0x0F4, 0x000 // FDD0
.byte 0x0F5, 0x000 // FDD1
.byte 0x030, 0x001 // activate
// LPT
// .byte 0x007, 0x003 // select
// .byte 0x060, 0x003
// .byte 0x061, 0x078 // I/O 378h
// .byte 0x070, 0x007 // IRQ 7
// .byte 0x074, 0x004 // no DMA
// .byte 0x0F0, 0x038 // SPP mode
// .byte 0x0F1, 0x000 // normal mode
// .byte 0x030, 0x001 // activate
// SER1
.byte 0x007, 0x004 // select
.byte 0x060, 0x003
.byte 0x061, 0x0f8 // I/O 3f8h
.byte 0x070, 0x004 // IRQ 4
.byte 0x0F0, 0x000 // normal
.byte 0x030, 0x001 // activate
// SER2
.byte 0x007, 0x005 // select
.byte 0x060, 0x002
.byte 0x061, 0x0f8 // I/O 2f8h
.byte 0x070, 0x003 // IRQ 3
.byte 0x0F0, 0x000 // normal
// .byte 0x0F1, 0x002 // IR default
// .byte 0x0F2, 0x003 // IR default
.byte 0x030, 0x001 // activate
// RTC
.byte 0x007, 0x006 // select
.byte 0x070, 0x008 // IRQ 8
.byte 0x0F0, 0x030 // bank 0 at 70h
.byte 0x030, 0x001 // activate
// KBDC
.byte 0x007, 0x007 // select
.byte 0x070, 0x001 // IRQ 1
.byte 0x072, 0x00C // IRQ 12 for PS/2 mouse
.byte 0x0F0, 0x000 // reset & gate A20 default (smg: uncommented)
.byte 0x030, 0x001 // activate
// Aux I/O
.byte 0x007, 0x008 // select
.byte 0x0C0, 0x05F // IRQ control
.byte 0x0D0, 0x008 // enable IRQ 1
.byte 0x0D1, 0x008 // enable IRQ 3
.byte 0x0D2, 0x008 // enable IRQ 4
.byte 0x0D3, 0x008 // enable IRQ 5
.byte 0x0D4, 0x008 // enable IRQ 6
.byte 0x0D5, 0x008 // enable IRQ 7
.byte 0x0D6, 0x008 // enable IRQ 8
.byte 0x0D7, 0x008 // enable IRQ 10
.byte 0x0CB, 0x008 // enable IRQ 11
.byte 0x0CC, 0x008 // enable IRQ 12
.byte 0x0CA, 0x001 // enable DRVDEN1
.byte 0x0E1, 0x000 // GP11 output (external 27MHz)
.byte 0x0E4, 0x000 // GP14 output (video YUV)
.byte 0x0E5, 0x000 // GP15 output (DDC line)
.byte 0x0E6, 0x008 // enable MTR1
.byte 0x0E7, 0x008 // enable DS1
.byte 0x030, 0x001 // activate
// ACPI
.byte 0x007, 0x00A // select
.byte 0x030, 0x000 // de-activate
SioTableEnd = .
stpc_superio0:

View file

@ -0,0 +1,305 @@
// you can't make this stuff common. Things change a lot from superio to superio. sorry.
#include <pci.h>
#include <cpu/p5/io.h>
#include <serial_subr.h>
#include <printk.h>
#include <pc80/keyboard.h>
// just define these here. We may never need them anywhere else
#define FLOPPY_DEVICE 0
#define PARALLEL_DEVICE 3
#define COM1_DEVICE 4
#define COM2_DEVICE 5
#define KBC_DEVICE 7
#define GPIO_PORT2_DEVICE 8
#define ACPI_DEVICE 0xa
#define FLOPPY_DEFAULT_IOBASE 0x3f0
#define FLOPPY_DEFAULT_IRQ 6
#define FLOPPY_DEFAULT_DRQ 2
#define PARALLEL_DEFAULT_IOBASE 0x378
#define PARALLEL_DEFAULT_IRQ 7
#define PARALLEL_DEFAULT_DRQ 4 /* No dma */
#define COM1_DEFAULT_IOBASE 0x3f8
#define COM1_DEFAULT_IRQ 4
#define COM1_DEFAULT_BAUD 115200
#define COM2_DEFAULT_IOBASE 0x2f8
#define COM2_DEFAULT_IRQ 3
#define COM2_DEFAULT_BAUD 115200
#define KBC_DEFAULT_IOBASE0 0x60
#define KBC_DEFAULT_IOBASE1 0x64
#define KBC_DEFAULT_IRQ0 0x1
#define KBC_DEFAULT_IRQ1 0xc
// funny how all these chips are "pnp compatible", and they're all different.
#define PNPADDR 0x3f0
void
enter_pnp(struct superio *sio)
{
// unlock it XXX make this a subr at some point
outb(0x55, sio->port);
}
void
exit_pnp(struct superio *sio)
{
/* all done. */
// select configure control
outb(0xaa, sio->port);
}
static void write_config(struct superio *sio,
unsigned char value, unsigned char reg)
{
outb(reg, sio->port);
outb(value, sio->port +1);
}
static unsigned char read_config(struct superio *sio, unsigned char reg)
{
outb(reg, sio->port);
return inb(sio->port +1);
}
static void set_logical_device(struct superio *sio, int device)
{
write_config(sio, device, 0x07);
}
static void set_irq0(struct superio *sio, unsigned irq)
{
write_config(sio, irq, 0x70);
}
static void set_irq1(struct superio *sio, unsigned irq)
{
write_config(sio, irq, 0x72);
}
static void set_drq(struct superio *sio, unsigned drq)
{
write_config(sio, drq & 0xff, 0x74);
}
static void set_iobase0(struct superio *sio, unsigned iobase)
{
write_config(sio, (iobase >> 8) & 0xff, 0x60);
write_config(sio, iobase & 0xff, 0x61);
}
static void set_iobase1(struct superio *sio, unsigned iobase)
{
write_config(sio, (iobase >> 8) & 0xff, 0x62);
write_config(sio, iobase & 0xff, 0x63);
}
static void set_enable(struct superio *sio, int enable)
{
write_config(sio, enable?0x1:0x0, 0x30);
#if 0
if (enable) {
printk_debug("enabled superio device: %d\n",
read_config(sio, 0x07));
}
#endif
}
static void setup_parallel(struct superio *sio)
{
/* Remember the default resources */
unsigned iobase = PARALLEL_DEFAULT_IOBASE;
unsigned irq = PARALLEL_DEFAULT_IRQ;
unsigned drq = PARALLEL_DEFAULT_DRQ;
/* Select the device */
set_logical_device(sio, PARALLEL_DEVICE);
/* Disable it while initializing */
set_enable(sio, 0);
if (sio->lpt) {
set_iobase0(sio, iobase);
set_irq0(sio, irq);
set_drq(sio, drq);
set_enable(sio, 1);
}
}
// test a non-fifo uart init. Stupid chip.
/* Line Control Settings */
#ifndef TTYS0_LCS
/* Set 8bit, 1 stop bit, no parity */
#define TTYS0_LCS 0x3
#endif
#define UART_LCS TTYS0_LCS
/* Data */
#define UART_RBR 0x00
#define UART_TBR 0x00
/* Control */
#define UART_IER 0x01
#define UART_IIR 0x02
#define UART_FCR 0x02
#define UART_LCR 0x03
#define UART_MCR 0x04
#define UART_DLL 0x00
#define UART_DLM 0x01
/* Status */
#define UART_LSR 0x05
#define UART_MSR 0x06
#define UART_SCR 0x07
inline void uart_init_nofifo(unsigned base_port, unsigned divisor)
{
/* disable interrupts */
outb(0x0, base_port + UART_IER);
#if 0
/* enable fifo's */
outb(0x01, base_port + UART_FCR);
#else
outb(0x06, base_port + UART_FCR);
#endif
/* Set Baud Rate Divisor to 12 ==> 115200 Baud */
outb(0x80 | UART_LCS, base_port + UART_LCR);
outb(divisor & 0xFF, base_port + UART_DLL);
outb((divisor >> 8) & 0xFF, base_port + UART_DLM);
outb(UART_LCS, base_port + UART_LCR);
}
#ifndef SERIAL_CONSOLE
inline void uart_init (unsigned base_port, unsigned divisor)
{
/* disable interrupts */
outb(0x0, base_port + UART_IER);
/* enable fifo's */
outb(0x01, base_port + UART_FCR);
/* Set Baud Rate Divisor to 12 ==> 115200 Baud */
outb(0x80 | UART_LCS, base_port + UART_LCR);
outb(divisor & 0xFF, base_port + UART_DLL);
outb((divisor >> 8) & 0xFF, base_port + UART_DLM);
outb(UART_LCS, base_port + UART_LCR);
}
#endif
static void setup_com(struct superio *sio,
struct com_ports *com, int device)
{
// set baud, default to 115200 if not set.
int divisor = 115200/(com->baud ? com->baud : 1);
printk_debug("%s com device: %02x\n",
com->enable? "Enabling" : "Disabling", device);
/* Select the device */
set_logical_device(sio, device);
/* Disable it while it is initialized */
set_enable(sio, 0);
if (com->enable) {
printk_debug(" iobase = 0x%04x irq=%d\n",
com->base, com->irq);
set_iobase0(sio, com->base);
set_irq0(sio, com->irq);
/* We are initialized so enable the device */
set_enable(sio, 1);
/* Now initialize the com port */
uart_init(com->base, divisor);
}
}
static void setup_floppy(struct superio *sio)
{
/* Remember the default resources */
unsigned iobase = FLOPPY_DEFAULT_IOBASE;
unsigned irq = FLOPPY_DEFAULT_IRQ;
unsigned drq = FLOPPY_DEFAULT_DRQ;
/* Select the device */
set_logical_device(sio, FLOPPY_DEVICE);
/* Disable it while initializing */
set_enable(sio, 0);
if (sio->floppy) {
set_iobase0(sio, iobase);
set_irq0(sio, irq);
set_drq(sio, drq);
set_enable(sio, 1);
}
}
#ifndef NO_KEYBOARD
static void setup_keyboard(struct superio *sio)
{
/* Remember the default resources */
unsigned iobase0 = KBC_DEFAULT_IOBASE0;
unsigned iobase1 = KBC_DEFAULT_IOBASE1;
unsigned irq0 = KBC_DEFAULT_IRQ0;
unsigned irq1 = KBC_DEFAULT_IRQ1;
/* Select the device */
set_logical_device(sio, KBC_DEVICE);
/* Disable it while initializing */
set_enable(sio, 0);
if (sio->keyboard) {
set_iobase0(sio, iobase0);
set_iobase1(sio, iobase1);
set_irq0(sio, irq0);
set_irq1(sio, irq1);
set_enable(sio, 1);
/* Initialize the keyboard */
pc_keyboard_init();
}
}
#endif
static void setup_devices(struct superio *sio)
{
if (sio->port == 0) {
sio->port = sio->super->defaultport;
}
if (sio->com1.base == 0) sio->com1.base = COM1_DEFAULT_IOBASE;
if (sio->com1.irq == 0) sio->com1.irq = COM1_DEFAULT_IRQ;
if (sio->com1.baud == 0) sio->com1.baud = COM1_DEFAULT_BAUD;
if (sio->com2.base == 0) sio->com2.base = COM2_DEFAULT_IOBASE;
if (sio->com2.irq == 0) sio->com2.irq = COM2_DEFAULT_IRQ;
if (sio->com2.baud == 0) sio->com2.baud = COM2_DEFAULT_BAUD;
enter_pnp(sio);
/* enable/disable floppy */
setup_floppy(sio);
/* enable or disable parallel */
setup_parallel(sio);
/* enable/disable com1 */
setup_com(sio, &sio->com1, COM1_DEVICE);
/* enable/disable com2 */
setup_com(sio, &sio->com2, COM2_DEVICE);
#ifndef NO_KEYBOARD
/* enable/disable keyboard */
setup_keyboard(sio);
#endif
/* gpio_port2 */
set_logical_device(sio, GPIO_PORT2_DEVICE);
set_enable(sio, sio->gpio2);
/* enable/disable acpi */
set_logical_device(sio, ACPI_DEVICE);
set_enable(sio, sio->acpi);
exit_pnp(sio);
}
struct superio_control superio_SMC_fdc37b78x_control = {
pre_pci_init: (void *) 0,
init: setup_devices,
finishup: (void *) 0,
defaultport: PNPADDR,
name: "SMC fdc37b72x"
};

View file

@ -0,0 +1,94 @@
# Config file for PCCHIPS m787cl+
# with vga and graphics logo display
# uses flash, ide, and optionally floppy
# no doc mem.
#
# by Steve M. Gehlbach <steve@kesa.com>
#
# This will dump files in directory of /usr/src/pcchips
target /usr/src/pcchips787
# PCCHIPS m787cl+ mainboard
mainboard pcchips/m787cl+
#this sets the vga memory small since
#text console uses very little
option SMA_SIZE=0x80
option CONFIG_COMPRESS=0
# you have to relocate the gdt before
# jumping to linux if you put the flash code
# here.
biosbase 0xffff0000
# For printk_debug, set level to 8
# for printk_info, set level to 7
#option DEFAULT_CONSOLE_LOGLEVEL=8
#option DEFAULT_CONSOLE_LOGLEVEL=7
option DEFAULT_CONSOLE_LOGLEVEL=6
# STD_FLASH=1 is not necessary since we relocate the
# gdt in chipinit.inc. Turning on the shadow
# ram is thereofore okay. It does not wipe out the gdt.
#option STD_FLASH=1
# Enable Serial Console for debugging
# Enable VGA and logo splash screen
option VIDEO_CONSOLE=1
option VIDEO_SHOW_LOGO=1
#
# the logo is displayed for VIDEO_SHOW_LOGO seconds.
# Need to have to have a 128k rom since the logo image is at the
# beginning (0xfffe0000)
option VIDEO_SHOW_LOGO=10
option ROM_IMAGE_SIZE=131072
option PCX_FILE_LOCATION=0xfffe0000
option SERIAL_CONSOLE=1
#option SERIAL_POST=1
# setup delay using TSC
# also set option in cpu/p5 to use timer2 to calibrate
option CONFIG_UDELAY_TSC=1
#floppy is nice
option MUST_ENABLE_FLOPPY=1
# the floppy/ide needs linux.gz and a ramdisk
# at the offset in the command line below
#option BOOT_FLOPPY=1
option BOOT_IDE=1
option IDE_BOOT_DRIVE=2
#need to know size of partition table for ide
option ONE_TRACK=32
# Use the internal VGA frame buffer device
# very important; crashes otherwise
option HAVE_FRAMEBUFFER=1
# Path to your kernel (vmlinux)
#linux /usr/src/linux-2.4.19
linux /usr/src/linux
# Kernel command line parameters
#commandline root=/dev/hda2 console=ttyS0,38400n8 console=/dev/tty0
#commandline root=/dev/hda1 console=/dev/tty0 console=ttyS0,38400n8
#commandline root=/dev/hda1 ro
commandline root=/dev/hda1 ro reboot=h
#
# these actions put the pcx image file on the front of the bios.
# the image size is placed in the first 4 bytes then the pcx file
# important that ROM_IMAGE_SIZE be set to 128K or larger.
# The logo file is called linuxbioslogo.pcx and should be copied to the build directory
#
addaction linuxbios.rom dd if=$(TOP)/src/pc80/linuxbioslogo.pcx of=linuxbios.rom bs=1 seek=4 conv=notrunc;
addaction linuxbios.rom perl -e '@a=stat "$(TOP)/src/pc80/linuxbioslogo.pcx";$$a=pack("L",$$a[7]); print $$a' | dd of=linuxbios.rom bs=1 conv=notrunc
# copy to home dir where flash programmer can reach.
addaction linuxbios.rom /bin/cp -f linuxbios.rom $(HOME)/linuxbios_787.bin

88
util/config/stpc.config Normal file
View file

@ -0,0 +1,88 @@
#
# config file for stpc consumer II with vga and
# graphics logo display
# uses flash, ide, and optionally floppy
# no doc mem.
#
# by Steve M. Gehlbach <steve@kesa.com>
#
# This will dump all the files in /usr/src/stpc_build
target /usr/src/stpc_new
# stpc consumer2
mainboard stpc/consumer2
biosbase 0xffff0000
option CONFIG_COMPRESS=0
# For printk_debug, set level to 8
# for printk_info, set level to 7
# for printk_notice, set level to 6
#option DEFAULT_CONSOLE_LOGLEVEL=8
option DEFAULT_CONSOLE_LOGLEVEL=6
# Enable Serial Console for debugging
option VIDEO_CONSOLE=1
# the logo is displayed for VIDEO_SHOW_LOGO seconds
# have to have a 128k rom since the image is at the
# beginning (0xfffe0000)
option VIDEO_SHOW_LOGO=10
option ROM_IMAGE_SIZE=131072
option PCX_FILE_LOCATION=0xfffe0000
option SERIAL_CONSOLE=1
# uncomment if debugging
#option SERIAL_POST=1
#floppy is nice
option MUST_ENABLE_FLOPPY=1
option CONFIG_UDELAY_TIMER2=1
#for elfboot
#option USE_ELF_BOOT=1
#option USE_GENERIC_ROM=1
#option ZKERNEL_START=0xfffe0000
# if you boot using a floppy,
# the floppy/ide needs linux.gz and a ramdisk
# at the offset in the linux commandline below
# option BOOT_FLOPPY=1
# for ide, this is set for linux at part1 raw
# on an ide drive (CF in this case) at ide=2
# and the linux rootfs on ide=0 in part1. see linux command line below.
option BOOT_IDE=1
option IDE_BOOT_DRIVE=2
# need to know size of partition table for ide
option ONE_TRACK=32
# Path to your kernel (vmlinux)
linux /usr/src/linux/
# Kernel command line parameters
# commandline rw load_ramdisk=1 prompt_ramdisk=0 ramdisk_start=750 root=/dev/fd0 console=ttyS0,38400n8
# commandline rw load_ramdisk=1 prompt_ramdisk=0 ramdisk_start=750 root=/dev/fd0 console=tty0
commandline root=/dev/hda1 ro reboot=h
#addaction linuxbios.rom dd conv=sync if=tulip.elf of=tulipelfimage bs=65536
#addaction linuxbios.rom cat tulipelfimage linuxbios.rom >romelfimage
#addaction linuxbios.rom /bin/cp -f romelfimage /home/staff/steve/cti/software/bios/exp/
#
# these actions put the pcx image file on the front of the bios.
# the image size is placed in the first 4 bytes then the pcx file
# important that ROM_IMAGE_SIZE be set to 128K or larger.
# The logo file is called linuxbioslogo.pcx and should be copied to the build directory
#
addaction linuxbios.rom dd if=$(TOP)/src/pc80/linuxbioslogo.pcx of=linuxbios.rom bs=1 seek=4 conv=notrunc;
addaction linuxbios.rom perl -e '@a=stat "$(TOP)/src/pc80/linuxbioslogo.pcx";$$a=pack("L",$$a[7]); print $$a' | dd of=linuxbios.rom bs=1 conv=notrunc
# copy to home dir where flash programmer can reach.
addaction linuxbios.rom /bin/cp -f linuxbios.rom $(HOME)/linuxbios_stpc.bin