From 1103ba3c2adf8bd0bb37219fb9eb4f8d331f5022 Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Mon, 8 Mar 2004 15:22:30 +0000 Subject: [PATCH] STPC ELITE! --- src/cpu/stpc/elite/Config | 1 + src/cpu/stpc/elite/smbus_elite.inc | 216 +++++++++++++ src/cpu/stpc/elite/stpc_cache.inc | 66 ++++ src/cpu/stpc/elite/stpc_chip.inc | 269 ++++++++++++++++ src/cpu/stpc/elite/stpc_conf.c | 38 +++ src/cpu/stpc/elite/stpc_framebuffer.inc | 33 ++ src/cpu/stpc/elite/stpc_ioinit.inc | 158 ++++++++++ src/cpu/stpc/elite/stpc_memsize.inc | 295 ++++++++++++++++++ src/cpu/stpc/elite/stpc_ram_init.inc | 27 ++ src/cpu/stpc/elite/stpc_shadow_ram.inc | 86 +++++ src/include/cpu/stpc/elite/stpc.h | 128 ++++++++ .../cpu/stpc/elite/stpc_conf-notused.h | 9 + src/mainboard/stpc/elite/Config | 35 +++ src/mainboard/stpc/elite/STATUS | 30 ++ src/mainboard/stpc/elite/irq_tables.c | 40 +++ src/mainboard/stpc/elite/mainboard.c | 208 ++++++++++++ src/mainboard/stpc/elite/stpc-example.config | 21 ++ src/northsouthbridge/stpc/elite/Config | 7 + src/northsouthbridge/stpc/elite/nsbridge.c | 70 +++++ util/flash_and_burn/am29f040b.c | 2 +- 20 files changed, 1738 insertions(+), 1 deletion(-) create mode 100644 src/cpu/stpc/elite/Config create mode 100644 src/cpu/stpc/elite/smbus_elite.inc create mode 100644 src/cpu/stpc/elite/stpc_cache.inc create mode 100644 src/cpu/stpc/elite/stpc_chip.inc create mode 100644 src/cpu/stpc/elite/stpc_conf.c create mode 100644 src/cpu/stpc/elite/stpc_framebuffer.inc create mode 100644 src/cpu/stpc/elite/stpc_ioinit.inc create mode 100644 src/cpu/stpc/elite/stpc_memsize.inc create mode 100644 src/cpu/stpc/elite/stpc_ram_init.inc create mode 100644 src/cpu/stpc/elite/stpc_shadow_ram.inc create mode 100644 src/include/cpu/stpc/elite/stpc.h create mode 100644 src/include/cpu/stpc/elite/stpc_conf-notused.h create mode 100644 src/mainboard/stpc/elite/Config create mode 100644 src/mainboard/stpc/elite/STATUS create mode 100644 src/mainboard/stpc/elite/irq_tables.c create mode 100644 src/mainboard/stpc/elite/mainboard.c create mode 100644 src/mainboard/stpc/elite/stpc-example.config create mode 100644 src/northsouthbridge/stpc/elite/Config create mode 100644 src/northsouthbridge/stpc/elite/nsbridge.c diff --git a/src/cpu/stpc/elite/Config b/src/cpu/stpc/elite/Config new file mode 100644 index 0000000000..4a7185bb8e --- /dev/null +++ b/src/cpu/stpc/elite/Config @@ -0,0 +1 @@ +object stpc_conf.o diff --git a/src/cpu/stpc/elite/smbus_elite.inc b/src/cpu/stpc/elite/smbus_elite.inc new file mode 100644 index 0000000000..42a8053df0 --- /dev/null +++ b/src/cpu/stpc/elite/smbus_elite.inc @@ -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 + diff --git a/src/cpu/stpc/elite/stpc_cache.inc b/src/cpu/stpc/elite/stpc_cache.inc new file mode 100644 index 0000000000..42a351b14d --- /dev/null +++ b/src/cpu/stpc/elite/stpc_cache.inc @@ -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) diff --git a/src/cpu/stpc/elite/stpc_chip.inc b/src/cpu/stpc/elite/stpc_chip.inc new file mode 100644 index 0000000000..6146cf7a66 --- /dev/null +++ b/src/cpu/stpc/elite/stpc_chip.inc @@ -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: diff --git a/src/cpu/stpc/elite/stpc_conf.c b/src/cpu/stpc/elite/stpc_conf.c new file mode 100644 index 0000000000..2b6b544f27 --- /dev/null +++ b/src/cpu/stpc/elite/stpc_conf.c @@ -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 +#include +#include + +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); +} diff --git a/src/cpu/stpc/elite/stpc_framebuffer.inc b/src/cpu/stpc/elite/stpc_framebuffer.inc new file mode 100644 index 0000000000..572e5d3703 --- /dev/null +++ b/src/cpu/stpc/elite/stpc_framebuffer.inc @@ -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 + diff --git a/src/cpu/stpc/elite/stpc_ioinit.inc b/src/cpu/stpc/elite/stpc_ioinit.inc new file mode 100644 index 0000000000..a8b8115ee1 --- /dev/null +++ b/src/cpu/stpc/elite/stpc_ioinit.inc @@ -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 diff --git a/src/cpu/stpc/elite/stpc_memsize.inc b/src/cpu/stpc/elite/stpc_memsize.inc new file mode 100644 index 0000000000..5df0fc55f4 --- /dev/null +++ b/src/cpu/stpc/elite/stpc_memsize.inc @@ -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: diff --git a/src/cpu/stpc/elite/stpc_ram_init.inc b/src/cpu/stpc/elite/stpc_ram_init.inc new file mode 100644 index 0000000000..639fb57694 --- /dev/null +++ b/src/cpu/stpc/elite/stpc_ram_init.inc @@ -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 diff --git a/src/cpu/stpc/elite/stpc_shadow_ram.inc b/src/cpu/stpc/elite/stpc_shadow_ram.inc new file mode 100644 index 0000000000..1eaa9ad5f5 --- /dev/null +++ b/src/cpu/stpc/elite/stpc_shadow_ram.inc @@ -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: diff --git a/src/include/cpu/stpc/elite/stpc.h b/src/include/cpu/stpc/elite/stpc.h new file mode 100644 index 0000000000..536a4ae608 --- /dev/null +++ b/src/include/cpu/stpc/elite/stpc.h @@ -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 */ diff --git a/src/include/cpu/stpc/elite/stpc_conf-notused.h b/src/include/cpu/stpc/elite/stpc_conf-notused.h new file mode 100644 index 0000000000..1c980ee6ee --- /dev/null +++ b/src/include/cpu/stpc/elite/stpc_conf-notused.h @@ -0,0 +1,9 @@ +#ifndef STPC_CONF_H +#define STPC_CONF_H + +#include + +extern u8 stpc_conf_readb( u8 port); +extern void stpc_conf_writeb( u8 data, u8 port); + +#endif diff --git a/src/mainboard/stpc/elite/Config b/src/mainboard/stpc/elite/Config new file mode 100644 index 0000000000..c611ae1292 --- /dev/null +++ b/src/mainboard/stpc/elite/Config @@ -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 + diff --git a/src/mainboard/stpc/elite/STATUS b/src/mainboard/stpc/elite/STATUS new file mode 100644 index 0000000000..39e9c98b84 --- /dev/null +++ b/src/mainboard/stpc/elite/STATUS @@ -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 diff --git a/src/mainboard/stpc/elite/irq_tables.c b/src/mainboard/stpc/elite/irq_tables.c new file mode 100644 index 0000000000..3ca7b7ff70 --- /dev/null +++ b/src/mainboard/stpc/elite/irq_tables.c @@ -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 +#include + +// +// 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}, + } +}; diff --git a/src/mainboard/stpc/elite/mainboard.c b/src/mainboard/stpc/elite/mainboard.c new file mode 100644 index 0000000000..9702bd3f6f --- /dev/null +++ b/src/mainboard/stpc/elite/mainboard.c @@ -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 + * edit with ts=4 + * + * Also works for the STPC Elite eval board. (Peter Fox) + * + */ +#include + +#include +#include +#include + +//////////////////////////////////////////////////////////////// +// // +// 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;isize;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< 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; +} diff --git a/src/mainboard/stpc/elite/stpc-example.config b/src/mainboard/stpc/elite/stpc-example.config new file mode 100644 index 0000000000..9c7798fc54 --- /dev/null +++ b/src/mainboard/stpc/elite/stpc-example.config @@ -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 diff --git a/src/northsouthbridge/stpc/elite/Config b/src/northsouthbridge/stpc/elite/Config new file mode 100644 index 0000000000..db0748e599 --- /dev/null +++ b/src/northsouthbridge/stpc/elite/Config @@ -0,0 +1,7 @@ +# +# by Steve M. Gehlbach +# +option STPC_ELITE=1 + +object nsbridge.c + diff --git a/src/northsouthbridge/stpc/elite/nsbridge.c b/src/northsouthbridge/stpc/elite/nsbridge.c new file mode 100644 index 0000000000..02d13e97b1 --- /dev/null +++ b/src/northsouthbridge/stpc/elite/nsbridge.c @@ -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 +#include +#include + +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; +} + diff --git a/util/flash_and_burn/am29f040b.c b/util/flash_and_burn/am29f040b.c index ae345e54d8..9d770cf4b1 100644 --- a/util/flash_and_burn/am29f040b.c +++ b/util/flash_and_burn/am29f040b.c @@ -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;