STPC ELITE!

This commit is contained in:
Ronald G. Minnich 2004-03-08 15:22:30 +00:00
commit 1103ba3c2a
20 changed files with 1738 additions and 1 deletions

View file

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

View file

@ -0,0 +1,216 @@
jmp smbus_elite_init
// Bit bashing spd code for the STPC
//
// Copyright (C) 2004 Aeroflex International Limited
// peter.fox @ aeroflex.com, Longacres House, Six Hills Way, Stevenage, SG1 2AN, UK.
//
// This software comes with ABSOLUTELY NO WARRANTY; This is free software, and
// you are welcome to redistribute it under certain conditions; you can
// redistribute it and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation version 2 of the
// License.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
// more details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc., 675 Mass
// Ave, Cambridge, MA 02139, USA. "
//
#define DDC_CLOCK_BIT 1
#define DDC_DATA_BIT 2
//
// 66 corresponds to 5us delay at 133MHz CPU clock, with no wait states
// -> 100kHz SPD clock
// In practice this gives ~1ms, due to the slow ISA bus speed.
//
#define DDC_WRITE_DELAY 2
/*
* Macro: SetDDC
* Arguments: Value to write in al
* Results: none
* Trashed: al, ecx
* Effects: Sets the DDC lines as told, and delays at least 5us
*/
#define SetDDC\
movb %al, %cl;\
movb $0x97, %al;\
outb %al, $STPC_CONF_REG_INDEX;\
inb $STPC_CONF_REG_DATA, %al;\
movb %al, %ch;\
andb $0xF0, %ch;\
andb $DDC_CLOCK_BIT | DDC_DATA_BIT, %cl;\
orb %cl, %ch;\
movb $0x97, %al;\
outb %al, $STPC_CONF_REG_INDEX;\
mov %ch, %al;\
outb %al, $STPC_CONF_REG_DATA;\
movl $DDC_WRITE_DELAY, %ecx;\
0: nop;\
loop 0b
/*
* Macro: ReadSDA
* Arguments: none
* Results: bit value returned in lsb of al
* Trashed: al
* Effects: Read state of the SDA line
*/
#define ReadSDA\
mov $0x97, %al;\
outb %al, $STPC_CONF_REG_INDEX;\
inb $STPC_CONF_REG_DATA, %al;\
shrb $3, %al;\
andb $1, %al
/*
* Macro: DDC_start
* Arguments: none
* Results: none
* Trashed: al, ecx
* Effects: Send spd start condition
*/
#define DDC_start\
mov $DDC_CLOCK_BIT | DDC_DATA_BIT, %al;\
SetDDC;\
mov $DDC_CLOCK_BIT, %al;\
SetDDC;\
xor %al,%al;\
SetDDC;
/*
* Macro: DDC_stop
* Arguments: none
* Results: none
* Trashed: al, ecx
* Effects: Send spd stop condition
*/
#define DDC_stop\
xor %al,%al;\
SetDDC;\
mov $DDC_CLOCK_BIT, %al;\
SetDDC;\
mov $DDC_CLOCK_BIT | DDC_DATA_BIT, %al;\
SetDDC;
/*
* Macro: DDC_send_8_bits
* Arguments: 8 bits in dl
* Results: Ack bit in ah
* Trashed: ax, dx, ecx
* Effects: Send 8 bits, and receive the acknowledge bit
*/
#define DDC_send_8_bits\
movb $8, %dh;\
2: xor %ah, %ah;\
testb $0x80, %dl;\
jz 1f;\
movb $DDC_DATA_BIT, %ah;\
1: movb %ah, %al;\
SetDDC;\
movb %ah, %al;\
orb $DDC_CLOCK_BIT, %al;\
SetDDC;\
movb %ah, %al;\
SetDDC;\
shlb $1, %dl;\
decb %dh;\
jnz 2b;\
mov $DDC_DATA_BIT, %al;\
SetDDC;\
mov $DDC_CLOCK_BIT | DDC_DATA_BIT, %al;\
SetDDC;\
ReadSDA;\
movb %al, %ah;\
mov $DDC_DATA_BIT, %al;\
SetDDC;\
testb $1, %ah
/*
* Macro: DDC_receive_8_bits
* Arguments: Ack bit in ah
* Results: Data byte in dl
* Trashed: ax, dx, ecx
* Effects: Receive 8 bits, and send the acknowledge bit
*/
#define DDC_receive_8_bits\
movb $8, %dh;\
xor %dl, %dl;\
1: mov $DDC_DATA_BIT, %al;\
SetDDC;\
mov $DDC_CLOCK_BIT | DDC_DATA_BIT, %al;\
SetDDC;\
ReadSDA;\
shlb $1, %dl;\
orb %al, %dl;\
decb %dh;\
jnz 1b;\
testb $0x01, %ah;\
jz 2f;\
movb $DDC_DATA_BIT, %dh;\
2: movb %dh, %al;\
SetDDC;\
movb %dh, %al;\
orb $DDC_CLOCK_BIT, %al;\
SetDDC;\
movb %dh, %al;\
SetDDC
/*
* Routine: smbus_read_byte
* Arguments: %esp return address
* %bl device on the smbus to read from
* %bh address on the smbus to read
*
* Results: zf clear (non-zero)
* byte read %eax
* On Error:
* zf set (zero)
* %eax trashed
*
* Trashed: %ecx, %edx, %eax
* Effects: reads a byte off of the smbus
*/
#define SMBUS_READ_BYTE(device, address) \
movl $( (device) | ((address) << 8)), %ebx ; \
CALLSP(smbus_read_byte)
smbus_read_byte:
/* Do a dummy write to set the device internal read pointer */
DDC_start
movb %bl /* device */, %dl
shlb $1, %dl
DDC_send_8_bits
jnz smbus_nodev
/* Set the address pointer */
movb %bh /* address */, %dl
DDC_send_8_bits
jnz smbus_nodev
/* Now do a read from current pointer */
DDC_start
movb %bl /* device */, %dl
shlb $1, %dl
orb $1, %dl
DDC_send_8_bits
jnz smbus_nodev
mov $1, %ah
DDC_receive_8_bits
mov %dl, %al
orb $1, %ah /* Non-zero result */
jmp 3f
smbus_nodev:
xor %al, %al /* Zero result */
3:
RETSP
smbus_elite_init:
mov $DDC_CLOCK_BIT | DDC_DATA_BIT, %dl
SetDDC

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,269 @@
/*
* Bootstrap code for the STPC Elite
*
* Modified by Peter Fox:
* SDRAM clock set to 100MHz
* GPIO clock initialised to 14.7312MHz
* Graphics stuff removed
* Added GPL header
*
* This software comes with ABSOLUTELY NO WARRANTY; This is free software, and
* you are welcome to redistribute it under certain conditions; you can
* redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation version 2 of the
* License.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 675 Mass
* Ave, Cambridge, MA 02139, USA. "
*
* from the Consumer II code
* 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/elite/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
/*
* Memory clock
*/
/*
* .byte 0x40, 0b10000000, 0x4b // m=9, n=166, p=3
* .byte 0x41, 0b00000000, 0xa6 // f= 66 Mhz
*/
.byte 0x40, 0b10000000, 0x5A // m=11, n=154, p=2
.byte 0x41, 0b00000000, 0x9A // f= 100 Mhz
/*
* GPIO clock
*/
.byte 0x42, 0b00000000, 0x6d // m=13, n=214, p=5
.byte 0x43, 0b00000000, 0xd6 // f=14.7312MHz (~1.8432 x 8)
/*
* 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,38 @@
/*
* Functions to Read/write the special configuration registers on the STPC
* by Steve M. Gehlbach
*
* Modified by Peter Fox:
* Header changed to elite version
* Added GPL header
*
* This software comes with ABSOLUTELY NO WARRANTY; This is free software, and
* you are welcome to redistribute it under certain conditions; you can
* redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation version 2 of the
* License.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 675 Mass
* Ave, Cambridge, MA 02139, USA. "
*
*/
#include <cpu/stpc/elite/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,295 @@
/*
* ram size detection for the STPC Elite
*
* Modified by Peter Fox:
* moved the DetectMemorySize symbol
* Support SPD timing for the Elite (Set option SPD_MEM_TIMING, uses default if fails)
* Support faster default memory timing (Set option SLOW_MEM for original)
* Note that have to initialise non-existant graphics memory for SDRAM to startup ok
* Added GPL header
*
* This software comes with ABSOLUTELY NO WARRANTY; This is free software, and
* you are welcome to redistribute it under certain conditions; you can
* redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation version 2 of the
* License.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 675 Mass
* Ave, Cambridge, MA 02139, USA. "
*
* From the STPC Consumer II version
*
* 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
DetectMemorySize:
movb $0x17, %al
outb %al, $0x80
#if (SPD_MEM_TIMING==1)
CALL_LABEL(stpc_read_spd_timing)
jnz 1f
#endif
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
1:
#if (SLOW_MEM==1)
// RCT=8 BL=7 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
#else
// RCT=7 BL=7 RRW=2 PRA=2 CASlat=2
// MRSR=1 RCASLCY=2
orl $7 + (0b111 << 4) + (2 << 8) + (2 << 15) + (2 << 19) \
+ (1 << 26) + (2 << 28), %eax
// TRC=7, TRCD=2, TRP=2, [4M*4]*16 (1024), CL=2,
// deassert RAS, update SDRAM, Read CL=CL
#endif
movl $STPC_MEM_REG0, %esi
movl %eax, %ds:(%esi)
movzx %bl, %eax
andb 0b00001111, %al // set read clock delay to minimum
orb 0b00011000, %al // enable 16mA
addw $4, %si // select STPC_MEM_REG1
movl %eax, %ds:(%esi)
#if 1
// Elite doesn't have graphic memory, but seems to need this to work
// 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
#endif
// 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,128 @@
#ifndef ROM_STPC_H
#define ROM_STPC_H
/*
* Bootstrap code for the STPC Elite
*
* Modified by Peter Fox:
* Removed graphics stuff
* Added GPL header
*
* This software comes with ABSOLUTELY NO WARRANTY; This is free software, and
* you are welcome to redistribute it under certain conditions; you can
* redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation version 2 of the
* License.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 675 Mass
* Ave, Cambridge, MA 02139, USA. "
*
* from Consumer II
* by Steve M. Gehlbach
*
* orig by: johryd
*
*
*/
/*
* 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,9 @@
#ifndef STPC_CONF_H
#define STPC_CONF_H
#include <types.h>
extern u8 stpc_conf_readb( u8 port);
extern void stpc_conf_writeb( u8 data, u8 port);
#endif

View file

@ -0,0 +1,35 @@
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/elite/stpc_chip.inc
mainboardinit cpu/stpc/elite/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/elite/stpc_ioinit.inc
mainboardinit cpu/stpc/elite/stpc_memsize.inc
mainboardinit cpu/stpc/elite/stpc_shadow_ram.inc
mainboardinit cpu/stpc/elite/stpc_cache.inc
northsouthbridge stpc/elite
nsuperio SMC/fdc37b78x com1={1,38400} floppy=1 lpt=1 keyboard=1
cpu stpc/elite
object mainboard.o
object irq_tables.o HAVE_PIRQ_TABLE

View file

@ -0,0 +1,30 @@
# These are keyword-value pairs.
# a : separates the keyword from the value
# the value is arbitrary text delimited by newline.
# continuation, if needed, will be via the \ at the end of a line
# comments are indicated by a '#' as the first character.
# the keywords are case-INSENSITIVE
#
# stpc Elite Evaluation Motherboard
#
owner: Peter Fox
email: peter.fox@aeroflex.com
#status: One of unsupported, unstable, stable
status: stable
explanation: okay
flash-types: AT49F040-70PC
payload-types: filo
# e.g. linux, plan 9, wince, etc.
OS-types: linux
# e.g. "Plan 9 interrupts don't work on this chipset"
OS-issues:
console-types: serial
# vga is unsupported, unstable, or stable
vga: unsupported
# Last-known-good follows the internationl date standard: day/month/year
last-known-good: 23/02/2004
Comments:
Links: http://www.stmcu.com/
Mainboard-revision: 1.1
# What other mainboards are like this one? List them here.
AKA: Same mainboard used for Consumer-II and Consumer-S

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,208 @@
/*
* 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
*
* Also works for the STPC Elite eval board. (Peter Fox)
*
*/
#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/elite
* 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;
}

View file

@ -0,0 +1,21 @@
target /home/fox/build/freebios1/stpc
mainboard stpc/elite
biosbase 0xffff0000
option CONFIG_COMPRESS=0
option ELITE_GPCLOCK_INIT=1
option SERIAL_CONSOLE=1
option TTYS0_BAUD=38400
option DEFAULT_CONSOLE_LOGLEVEL=9
#option MAXIMUM_CONSOLE_LOGLEVEL=9
option DEBUG=1
# option ROM_IMAGE_SIZE=131072
option ROM_SIZE=131072
option USE_GENERIC_ROM=1
option ZKERNEL_START=0xfffe0000
option USE_ELF_BOOT=1
option PAYLOAD_SIZE=65536
payload /home/fox/build/filo-0.4/filo.elf

View file

@ -0,0 +1,7 @@
#
# by Steve M. Gehlbach
#
option STPC_ELITE=1
object nsbridge.c

View file

@ -0,0 +1,70 @@
/*
* STPC basic initialization
* by
* Steve M. Gehlbach
*
* Most stpc work has to be done earlier
* so not much is in this file
*
* Modified by Peter Fox for the STPC Elite:
* Header changed to elite version
* Removed graphics stuff (No memory used for graphics)
* Added GPL header
*
* This software comes with ABSOLUTELY NO WARRANTY; This is free software, and
* you are welcome to redistribute it under certain conditions; you can
* redistribute it and/or modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation version 2 of the
* License.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; if not, write to the Free Software Foundation, Inc., 675 Mass
* Ave, Cambridge, MA 02139, USA. "
*
*/
#include <mem.h>
#include <cpu/p5/io.h>
#include <printk.h>
int display_cpuid ( void ) {
return 0;
}
int mtrr_check ( void ) {
return 0;
}
struct mem_range *sizeram(void)
{
static struct mem_range mem[3];
int mem_size;
// get ram size from settings in stpc SDRAM controller registers
// the last bank register = top memory in MB less one
mem_size = ( stpc_conf_readb(0x33) + 1 ) * 1024;
printk_info("stpc memory size= %d MB\n",mem_size/1024);
if (mem_size < 0 || mem_size > 128*1024) mem_size = 64*1024;
mem[0].basek = 0;
mem[0].sizek = 640;
mem[1].basek = 1024;
mem[1].sizek = mem_size;
mem[2].basek = 0;
mem[2].sizek = 0;
if (mem[1].sizek == 0) {
mem[1].sizek = 64*1024;
}
mem[1].sizek -= mem[1].basek;
return &mem[0];
}
int nvram_on ( void ) {
return 0;
}

View file

@ -92,7 +92,7 @@ int probe_29f040b (struct flashchip * flash)
int erase_29f040b (struct flashchip * flash)
{
volatile char * bios = flash->virt_addr;
volatile unsigned char * bios = flash->virt_addr;
*(bios + 0x555) = 0xAA;
*(bios + 0x2AA) = 0x55;