bitworks support. 440bx fixes.

This commit is contained in:
Ronald G. Minnich 2003-06-24 23:40:15 +00:00
parent 7883f9ffc1
commit 3ec74f3298
12 changed files with 1114 additions and 147 deletions

View file

@ -488,6 +488,7 @@ struct superio {
unsigned int keyboard, cir, game;
unsigned int gpio1, gpio2, gpio3;
unsigned int acpi,hwmonitor;
unsigned int mouse;
};
struct southbridge;

View file

@ -0,0 +1,44 @@
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
mainboardinit superio/NSC/pc87351/setup_serial.inc
mainboardinit pc80/serial.inc
mainboardinit arch/i386/lib/console.inc
northbridge intel/440bx
southbridge intel/piix4e
mainboardinit cpu/p6/earlymtrr.inc
#mainboardinit ram/dump_northbridge.inc
#mainboardinit ram/ramtest.inc
#mainboardinit mainboard/bitworks/ims/do_ramtest.inc
# These are for the dump SPD
option SMBUS_MEM_DEVICE_START=(0xa << 3)
option SMBUS_MEM_DEVICE_END=(SMBUS_MEM_DEVICE_START + 0x1)
option SMBUS_MEM_DEVICE_INC=1
#mainboardinit sdram/generic_dump_spd.inc
nsuperio NSC/pc87351 keyboard=1 com1={1} com2={1} floppy=0 lpt=0 mouse=1
option ENABLE_FIXED_AND_VARIABLE_MTRRS=1
option PIIX4_DEVFN=0x38
option CONFIG_UDELAY_TSC=1
# These options control if the IDE controller is enabled in the
# southbridge fixup code.
option CONFIG_LINUXBIOS_ENABLE_IDE=1
option CONFIG_LINUXBIOS_LEGACY_IDE=1
object mainboard.o
object irq_tables.o
cpu p6
cpu p5

View file

@ -0,0 +1,5 @@
mov $0x00000000, %eax
mov $0x0004ffff, %ebx
mov $16, %ecx
CALLSP(ramtest)

View file

@ -0,0 +1,36 @@
/* This file was generated by getpir.c, do not modify!
(but if you do, please run checkpir on it to verify)
Contains the IRQ Routing Table dumped directly from your memory , wich BIOS sets up
Documentation at : http://www.microsoft.com/hwdev/busbios/PCIIRQ.HTM
*/
#include <arch/pirq_routing.h>
const struct irq_routing_table intel_irq_routing_table = {
PIRQ_SIGNATURE, /* u32 signature */
PIRQ_VERSION, /* u16 version */
32+16*1, /* there can be total devices on the bus */
0, /* Where the interrupt router lies (bus) */
0x38, /* Where the interrupt router lies (dev) */
0xc00, /* IRQs devoted exclusively to PCI usage */
0x8086, /* Vendor */
0x7000, /* Device */
0, /* Crap (miniport) */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, /* u8 rfu[11] */
0x13, /* u8 checksum , this has to set to some value that would give 0 after the sum of all bytes for this structure (including checksum) */
{
/* {0,0x60, {{0x60, 0xdeb8}, {0x61, 0xdeb8}, {0x62, 0xdeb8}, {0x63, 0xdeb8}}, 0x1, 0},
{0,0x58, {{0x61, 0xdeb8}, {0x62, 0xdeb8}, {0x63, 0xdeb8}, {0x60, 0xdeb8}}, 0x2, 0},
{0,0x50, {{0x62, 0xdeb8}, {0x63, 0xdeb8}, {0x60, 0xdeb8}, {0x61, 0xdeb8}}, 0x3, 0},
{0,0x48, {{0x63, 0xdeb8}, {0x60, 0xdeb8}, {0x61, 0xdeb8}, {0x62, 0xdeb8}}, 0x4, 0},
{0,0x40, {{0x61, 0xdeb8}, {0x62, 0xdeb8}, {0x63, 0xdeb8}, {0x60, 0xdeb8}}, 0x5, 0},
{0,0x68, {{0x62, 0xdeb8}, {0x63, 0xdeb8}, {0x60, 0xdeb8}, {0x61, 0xdeb8}}, 0x6, 0},
{0,0x39, {{0x60, 0xdeb8}, {0x61, 0xdeb8}, {0x62, 0xdeb8}, {0x63, 0xdeb8}}, 0, 0},
*/
// USB bridge
{0,0x3a, {{0x0, 0xdeb8}, {0x0, 0xdeb8}, {0x0, 0xdeb8}, {0x63, 0xdeb8}}, 0, 0},
}
};

View file

@ -0,0 +1,181 @@
#include <printk.h>
#include <pci.h>
#include <cpu/p5/io.h>
void keyboard_on();
void southbridge_fixup();
// Body in the pixx4e/southbridge.c file
void disable_seconday_ide(void);
// this needs to be moved about a bit to northbridge.c etc.
void mainboard_fixup()
{
struct pci_dev *pm_pcidev, *host_bridge_pcidev, *nic_pcidev;
unsigned smbus_io, pm_io;
unsigned int i, j;
printk_debug("IMS mainboard_fixup()\n");
#if 1
pm_pcidev = pci_find_device(0x8086, 0x7113, 0);
host_bridge_pcidev = pci_find_slot(0, PCI_DEVFN(0,0));
#endif
#if 1
{
u8 byte;
u16 word;
u32 dword;
for(i = 0; i < 8; i++) {
pci_read_config_byte(host_bridge_pcidev, 0x60 +i, &byte);
printk_debug("DRB[i] = 0x%02x\n", byte);
}
pci_read_config_byte(host_bridge_pcidev, 0x57, &byte);
printk_debug("DRAMC = 0x%02x\n", byte);
pci_read_config_byte(host_bridge_pcidev, 0x74, &byte);
printk_debug("RPS = 0x%02x\n", byte);
pci_read_config_word(host_bridge_pcidev, 0x78, &word);
printk_debug("PGPOL = 0x%04x\n", word);
pci_read_config_dword(host_bridge_pcidev, 0x50, &dword);
printk_debug("NBXCFG = 0x%04x\n", dword);
}
#endif
#if 1
printk_debug("Reset Control Register\n");
outb(((inb(0xcf9) & 0x04) | 0x02), 0xcf9);
printk_debug("port 92\n");
outb((inb(0x92) & 0xFE), 0x92);
printk_debug("Disable Nmi\n");
outb(0, 0x70);
printk_debug("enabling smbus\n");
#if 0
smbus_io = NewPciIo(0x10);
#else
smbus_io = 0xFFF0;
#endif
pci_write_config_dword(pm_pcidev, 0x90, smbus_io | 1); /* iobase addr */
pci_write_config_byte(pm_pcidev, 0xd2, (0x4 << 1) | 1); /* smbus enable */
pci_write_config_word(pm_pcidev, 0x4, 1); /* iospace enable */
printk_debug("enable pm functions\n");
#if 0
pm_io = NewPciIo(0x40);
#else
pm_io = 0xFF80;
#endif
pci_write_config_dword(pm_pcidev, 0x40, pm_io | 1); /* iobase addr */
pci_write_config_byte(pm_pcidev, 0x80, 1); /* enable pm io address */
printk_debug("disabling smi\n");
/* GLBEN */
outw(0x00, pm_io + 0x20);
/* GLBCTL */
outl((1 << 24), pm_io + 0x28);
printk_debug("Disable more pm stuff\n");
/* PMEN */
outw((1 << 8), pm_io + 0x02);
/* PMCNTRL */
outw((0x5 << 10) , pm_io + 0x4);
/* PMTMR */
outl(0, pm_io + 0x08);
/* GPEN */
outw(0, pm_io + 0x0e);
/* PCNTRL */
outl(0, pm_io + 0x10);
/* GLBSTS */
/* DEVSTS */
/* GLBEN see above */
/* GLBCTL see above */
/* DEVCTL */
outl(0, pm_io + 0x2c);
/* GPIREG */
/* GPOREG */
printk_debug("Set the subsystem vendor id\n");
pci_write_config_word(host_bridge_pcidev, 0x2c, 0x8086);
printk_debug("Disabling pm stuff in pci config space\n");
#define MAX_COUNTERS
#ifndef MAX_COUNTERS
/* counters to 0 */
#define WHICH_COUNTERS(min,max) min
#else
/* max out the counters */
#define WHICH_COUNTERS(min,max) max
#endif
/* CNTA */
pci_write_config_dword(pm_pcidev, 0x44, WHICH_COUNTERS(0x004000f0, 0xFFFFFFFF));
/* CNTB */
pci_write_config_dword(pm_pcidev, 0x48, WHICH_COUNTERS(0x00000400, 0x007c07df));
/* GPICTL */
pci_write_config_dword(pm_pcidev, 0x4c, 0);
/* DEVRESD */
pci_write_config_dword(pm_pcidev, 0x50, 0);
/* DEVACTA */
pci_write_config_dword(pm_pcidev, 0x54, 0);
/* DEVACTB */
pci_write_config_dword(pm_pcidev, 0x58, 0);
/* DEVRESA */
pci_write_config_dword(pm_pcidev, 0x5c, 0);
/* DEVRESB */
pci_write_config_dword(pm_pcidev, 0x60, 0);
/* DEVRESC */
pci_write_config_dword(pm_pcidev, 0x64, 0); /* might kill the serial port */
/* DEVRESE */
pci_write_config_dword(pm_pcidev, 0x68, 0);
/* DEVRESF */
pci_write_config_dword(pm_pcidev, 0x6c, 0);
/* DEVRESG */
pci_write_config_dword(pm_pcidev, 0x70, 0);
/* DEVRESH */
pci_write_config_dword(pm_pcidev, 0x74, 0);
/* DEVRESI */
pci_write_config_dword(pm_pcidev, 0x78, 0);
/* DEVRESJ */
pci_write_config_dword(pm_pcidev, 0x7c, 0);
#endif
#if 1
/* Verify that smi is disabled */
printk_debug("Testing SMI\r\n");
{
u32 value;
pci_read_config_dword(pm_pcidev, 0x58, &value);
pci_write_config_dword(pm_pcidev, 0x58, value | (1 << 25));
}
outb(inb(0xb2), 0xb2);
printk_debug("SMI disabled\r\n");
#endif
disable_secondary_ide();
printk_debug( "Calling southbridge_fixup()\r\n");
southbridge_fixup();
}

View file

@ -2,6 +2,17 @@ jmp intel_440_out
#define USE_SPD 1
#define REGISTERED_DRAM $0x10
#define NONREGISTERED_DRAM $0x08
#define REGISTERED_DRAM_REGISTER $0x57
#define SMBUS_MEM_DEVICE_0 (0xa << 3)
#define SMBUS_MEM_DEVICE_1 (SMBUS_MEM_DEVICE_0 +1)
#define SMBUS_MEM_DEVICE_2 (SMBUS_MEM_DEVICE_0 +2)
#define SMBUS_MEM_DEVICE_3 (SMBUS_MEM_DEVICE_0 +3)
#define LAST_SMBUS_MEM_DEVICE (SMBUS_MEM_DEVICE_3)
#define CS_WRITE_BYTE(addr, byte) \
movl $addr, %eax ; \
movl $byte, %edx ; \
@ -16,8 +27,8 @@ jmp intel_440_out
movl $addr, %eax ; \
movl $dword, %ecx ; \
PCI_WRITE_CONFIG_DWORD
/* Default memory set to 0 */
/* Default memory set to 0 */
#define DRB 0x00
/* The DRB register for the first row */
@ -102,14 +113,15 @@ jmp intel_440_out
/* Default values for config registers */
#define SET_NBXCFG \
CS_WRITE_LONG(0x50, 0xff00a00c)
/* This insures refresh is off */
#define SET_DRAMC \
CS_WRITE_BYTE(0x57, 0x8) \
CS_WRITE_BYTE(0x57, 0x8)
/* PAM - Programmable Attribute Map Registers */
/* PAM - Programmable Attribute Map Registers */
/* Ideally we want to enable all of these as DRAM and teach
* linux it is o.k. to use them...
*/
@ -140,18 +152,18 @@ jmp intel_440_out
CS_WRITE_WORD(0x74, 0x0000)
#define SET_SDRAMC \
CS_WRITE_BYTE(0x76, 0x00)
CS_WRITE_BYTE(0x76, 0x00)
#define SET_PGPOL \
CS_WRITE_WORD(0x78, 0xff00)
/* PMCR - Power Management Control Register
Enable normal refresh operation and
the gated clock */
the gated clock */
#define SET_PMCR \
CS_WRITE_BYTE(0x7a, 0x14)
ram_set_registers:
ram_set_registers:
SET_NBXCFG
SET_DRAMC
SET_PAM
@ -177,7 +189,7 @@ ram_set_registers:
#define SMBHSTDAT1 6
#define SMBBLKDAT 7
enable_smbus:
enable_smbus:
CS_WRITE_LONG(PM_FUNCTION + 0x90, SMBUS_IO_BASE | 1) /* iobase addr */
CS_WRITE_BYTE(PM_FUNCTION + 0xd2, (0x4 << 1) | 1) /* smbus enable */
CS_WRITE_WORD(PM_FUNCTION + 0x4, 1) /* iospace enable */
@ -190,19 +202,13 @@ enable_smbus:
* Trashed: eax, edx
* Effects: The smbus is enabled
*/
setup_smbus:
setup_smbus:
mov $0x1e, %al
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
outb %al, %dx
RET_LABEL(setup_smbus)
#define SMBUS_MEM_DEVICE_0 (0xa << 3)
#define SMBUS_MEM_DEVICE_1 (SMBUS_MEM_DEVICE_0 +1)
#define SMBUS_MEM_DEVICE_2 (SMBUS_MEM_DEVICE_0 +2)
#define SMBUS_MEM_DEVICE_3 (SMBUS_MEM_DEVICE_0 +3)
smbus_wait_until_ready:
smbus_wait_until_ready:
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
1: inb %dx, %al
testb $1, %al
@ -224,7 +230,7 @@ smbus_read_byte:
/* clear any lingering errors, so that the transaction will run */
movl $(SMBUS_IO_BASE + SMBHSTSTAT), %edx
mov $0x1e, %al
mov $0x1e, %al
outb %al, %dx
/* set the device I'm talking to */
@ -262,106 +268,275 @@ smbus_read_byte:
1:
RETSP
configure_rps_pgpol_drb:
/* %bl is the row index */
xorl %ebx, %ebx
/*
* Routine: spd_set_drb
* Arguments: None
*
* Trashed: %eax, %ebx, %ecx, %edx, %esi, %edi, %ebp, %esp, %eflags
* Effects: Uses serial presence detect to set the
* DRB registers which holds the ending memory address assigned
* to each DIMM.
* Notes: %ebp holds the currently detected end of memory.
* %ebx holds the configuration port & SMBUS_MEM_DEVICE for
* the current iteration through the loop.
* %edi holds the memory size for the first side of the DIMM.
* %esi holds the memory size for the second side of the DIMM.
* memory size is represent as a power of 2.
* An unset memory size is represented as -1 ie. 0xFFFFFFFF
*/
/* %si is the aggregation of bits for RPS */
xorl %esi, %esi
/* %di has bits to be set in PGPOL */
spd_set_drb:
xorl %ebp, %ebp /* clear the memory address */
movl $((0x60 << 16) |SMBUS_MEM_DEVICE_0), %ebx
spd_set_drb_loop_top:
xorl %edi, %edi
subl $1, %edi
xorl %esi, %esi
subl $1, %esi
/* %cx holds the cumulative memory size of DIMMs */
xorl %ecx, %ecx
movb $3, %bh /* rows */
CALLSP(smbus_read_byte)
jnz 20f
andl $0xf, %eax
addl %eax, %edi
next_row:
movzx %bl, %dx
shl $16, %ebx
shr $1, %dx
mov $((5 << 8) | SMBUS_MEM_DEVICE_0), %bx
or %dx, %bx
CALLSP(smbus_read_byte)
jnz shift_before_moving_on
shr $16, %ebx
movb $4, %bh /* columns */
CALLSP(smbus_read_byte)
andl $0xf, %eax
addl %eax, %edi
testb $2, %al
jnz two_rows
testb $1, %bl
/* this used to be jnz but seems it should be jz */
jz ready_for_next_row
movb $17, %bh /* banks */
CALLSP(smbus_read_byte)
andl $0xff, %eax
bsrl %eax, %ecx
addl %ecx, %edi
two_rows:
movzx %bl, %dx
shl $16, %ebx
shr $1, %dx
mov $((4 << 8) | SMBUS_MEM_DEVICE_0), %bx
or %dx, %bx
CALLSP(smbus_read_byte)
shr $16, %ebx
subb $8, %al
shrd $2, %ax, %si
movzx %bl, %dx
shl $16, %ebx
shr $1, %dx
mov $((17 << 8) | SMBUS_MEM_DEVICE_0), %bx
or %dx, %bx
CALLSP(smbus_read_byte)
shr $16, %ebx
/* Get the module data width and convert it to a power of two */
movb $7, %bh /* (high byte) */
CALLSP(smbus_read_byte)
andl $0xff, %eax
movl %eax, %ecx
shll $8, %ecx
cmpb $4, %al
sete %al
shrd $1, %ax, %di
movb $6, %bh /* (low byte) */
CALLSP(smbus_read_byte)
andl $0xff, %eax
orl %eax, %ecx
bsrl %ecx, %eax
addl %eax, %edi
movzx %bl, %dx
shl $16, %ebx
shr $1, %dx
mov $((31 << 8) | SMBUS_MEM_DEVICE_0), %bx
or %dx, %bx
CALLSP(smbus_read_byte)
shr $16, %ebx
shr $1, %al
xorb %ah, %ah
add %ax, %cx
movzx %cx, %edx
movzx %bl, %eax
addl $0x60, %eax
/* now I have the ram size in bits as a power of two (less 1) */
subl $25, %edi /* Make it multiples of 8MB */
/* side two */
movb $5, %bh /* number of physical banks */
CALLSP(smbus_read_byte)
cmp $1, %al
jbe 20f
/* for now only handle the symmetrical case */
movl %edi, %esi
20:
/* Compute the end address for the DRB register */
cmpl $8, %edi /* Ignore the dimm if it is over 2GB */
jae 21f
movl $1, %eax
movl %edi, %ecx
shll %cl, %eax
addl %eax, %ebp
21:
/* Write the computed value for the first half of the DIMM */
movl %ebp, %edx /* value to write into %edx */
movl %ebx, %eax
shrl $16, %eax /* port address into %eax */
PCI_WRITE_CONFIG_BYTE
/* Compute the end address for the DRB register */
cmpl $8, %esi /* Ignore the dimm if it is over 2GB */
jae 30f
mov $1, %eax
movl %esi, %ecx
shll %cl, %eax
addl %eax, %ebp
30:
/* Write the comuputed value for the second half of the DIMM */
movl %ebp, %edx /* value to write into %edx */
movl %ebx, %eax
shrl $16, %eax /* port address into %eax */
addl $1, %eax /* The second half uses one port high */
PCI_WRITE_CONFIG_BYTE
addl $0x00020001, %ebx /* increment the smbus device & the config port */
cmpb $SMBUS_MEM_DEVICE_3, %bl /* see if I have reached the end */
jbe spd_set_drb_loop_top
/* o.k. I'm done return now */
RET_LABEL(spd_set_drb)
spd_set_dramc:
/* auto detect if ram is registered or not. */
/* The DRAMC register also contorls the refresh rate but we can't
* set that here because we must leave refresh disabled.
* see: spd_enable_refresh
*/
/* Find the first dimm and assume the rest are the same */
/* Load the smbus device and port int %ebx */
mov $((21 << 8) | SMBUS_MEM_DEVICE_0), %bx
1: CALLSP(smbus_read_byte)
jnz 2f
andl $0x12, %eax
jmp spd_set_dramc_out
2: addl $1, %ebx /* increment the device */
cmpb $LAST_SMBUS_MEM_DEVICE, %bl
jbe 1b
/* We couldn't find anything we must have no memory */
jmp no_memory
spd_set_dramc_out:
testb $0x12, %al
jz 2f
movl REGISTERED_DRAM, %eax
jmp 1f
shift_before_moving_on:
shr $16, %ebx
ready_for_next_row:
shr $2, %si
shr $1, %di
movzx %cx, %edx
movzx %bl, %eax
addl $0x60, %eax
2: movl NONREGISTERED_DRAM, %eax
1: movl %eax, %edx
movl REGISTERED_DRAM_REGISTER, %eax
PCI_WRITE_CONFIG_BYTE
1:
inc %bl
cmp MAX_ROWS, %bl
jb next_row
/* Now to finally write the RPS and PGPOL registers */
RET_LABEL(spd_set_dramc)
movzx %si, %ecx
/*
* Routine: spd_set_rps
* Arguments: None
*
* Trashed: %eax, %ebx, %ecx, %edx, %esi, %edi, %esp, %eflags
* Effects: Uses serial presence detect to set the row size
* on a given DIMM
* Notes: %esi accumulates the row sizes of all of the DIMMs
* %ecx holds the current bit into into %esi
* %bl holds the current SMBUS device
* FIXME: Check for illegal/unsupported ram configurations and abort
Richard Smith ported this from the 440gx board.
one thing to note is that the polarity of an error from
smbus_read_byte is opposite of the 440gx
*/
spd_set_rps:
/* The RPS register holds the size of a ``page'' of DRAM on each DIMM */
/* default all page sizes to 2KB */
xorl %esi, %esi
/* Index into %esi of bit to set */
movl $0 , %ecx
/* Load the smbus device into %ebx */
movl $SMBUS_MEM_DEVICE_0, %ebx
1: movb $4, %bh
CALLSP(smbus_read_byte) /* row address bits */
jnz 2f
andl $0xf, %eax
movl %eax, %edi
/* Number of colums indicates which row page size to use */
subl $8, %edi
jbe 2f
/* FIXME: do something with page sizes greather than 8KB!! */
shll %cl, %edi
orl %edi, %esi
/* side two */
movb $5, %bh
CALLSP(smbus_read_byte) /* number of physical banks */
cmp $1, %al
jbe 2f
/* for now only handle the symmtrical case */
shll $2, %edi
/* one too many shifts here. */
/* shll %cl, %edi*/
orl %edi, %esi
2: addl $1, %ebx /* increment the device */
addl $4, %ecx /* increment the shift count */
cmpb $SMBUS_MEM_DEVICE_3, %bl
jbe 1b
/* next block is for Ron's attempt to get registered to work. */
/* we have just verified that we have to have this code. It appears that
* the registered SDRAMs do indeed set the RPS wrong. sheesh.
*/
/* at this point, %esi holds the RPS for all ram.
* we have verified that for registered DRAM the values are
* 1/2 the size they should be. So we test for registered
* and then double the sizes if needed.
*/
movl $0x57, %eax
PCI_READ_CONFIG_BYTE
/* is it registered? */
testb $0x10, %eax
jz 1f
/* BIOS makes weird page size for registered! */
/* what we have found is you need to set the EVEN banks to
* twice the size. Fortunately there is a very easy way to
* do this. First, read the WORD value of register 0x74.
*/
/* now to double the size of the EVEN banks we only need to add 1 */
/* because the size is log2
*/
addl $0x1111, %esi
/* now write that final value of %esi into register 0x74 */
1:
movl %esi, %ecx
movl $0x74, %eax
PCI_WRITE_CONFIG_WORD
mov %di, %cx
movzx %ch, %edx
movl $0x79, %eax
PCI_WRITE_CONFIG_BYTE
PCI_WRITE_CONFIG_WORD
RET_LABEL(configure_rps_pgpol_drb)
RET_LABEL(spd_set_rps)
spd_set_pgpol:
/* The PGPOL register stores the number of logical banks per DIMM,
* and number of clocks the DRAM controller waits in the idle
* state.
*/
/* default all bank counts 2 */
xorl %esi, %esi
/* Index into %esi of bit to set */
movl $0 , %ecx
/* Load the smbus device into %ebx */
movl $SMBUS_MEM_DEVICE_0, %ebx
1: movb $17, %bh
CALLSP(smbus_read_byte) /* logical banks */
jnz 2f
cmp $0x4, %eax
jl 2f
movl $0x1, %eax
shll %cl, %eax
orl %eax, %esi
/* side two */
movb $5, %bh
CALLSP(smbus_read_byte) /* number of physical banks */
cmp $1, %al
jbe 2f
/* for now only handle the symmtrical case */
movl $0x2, %eax
shll %cl, %eax
orl %eax, %esi
2: addl $1, %ebx /* increment the device */
addl $2, %ecx /* increment the shift count */
cmpb $SMBUS_MEM_DEVICE_3, %bl
jbe 1b
shll $8, %esi
orl $0x7, %esi /* 32 clocks idle time */
movl %esi, %ecx
movl $0x78, %eax
PCI_WRITE_CONFIG_WORD
RET_LABEL(spd_set_pgpol)
configure_sdramc:
movl $((18 << 8) | SMBUS_MEM_DEVICE_0), %ebx
@ -380,28 +555,6 @@ configure_sdramc:
jbe 0b
2:
RET_LABEL(configure_sdramc)
spd_set_dramc:
movl $((21 << 8) | SMBUS_MEM_DEVICE_0), %ebx
1: CALLSP(smbus_read_byte)
jnz 2f
andl $0x12, %eax
jmp spd_set_dramc_out
2: addl $1, %ebx /* increment the device */
cmpb $SMBUS_MEM_DEVICE_3, %bl
jbe 1b
jmp no_memory
spd_set_dramc_out:
testb $0x2, %al
movl $8, %eax
jz 1f
movl $0x10, %eax
1: movl %eax, %edx
movl $0x57, %eax
PCI_WRITE_CONFIG_BYTE
RET_LABEL(spd_set_dramc)
/*
@ -415,7 +568,7 @@ spd_set_dramc_out:
* FIXME: Check for illegal/unsupported ram configurations and abort
*/
refresh_rates:
refresh_rates:
.byte 0x01 /* Normal 15.625 us -> 15.6 us */
.byte 0x05 /* Reduced(.25X) 3.9 us -> 7.8 us */
.byte 0x05 /* Reduced(.5X) 7.8 us -> 7.8 us */
@ -436,15 +589,15 @@ spd_enable_refresh:
cmpb $SMBUS_MEM_DEVICE_3, %bl
jbe 1b
/* We couldn't find anything we must have no memory */
jmp no_memory
jmp no_memory
spd_enable_refresh_out:
cmpb $0x06, %al
cmpb $0x06, %al
ja 1f
addl $refresh_rates, %eax
addl $refresh_rates, %eax
movb (%eax), %cl
jmp 2f
1: movb $0x05, %cl
1: movb $0x05, %cl
2: movl $0x57, %eax
PCI_READ_CONFIG_BYTE
andb $0xf8, %al
@ -461,7 +614,7 @@ spd_set_nbxcfg:
movl $0 , %ecx
/* Load the smbus device into %ebx */
movl $SMBUS_MEM_DEVICE_0, %ebx
1: movb $11, %bh
CALLSP(smbus_read_byte) /* module error correction type */
jnz 2f
@ -470,7 +623,7 @@ spd_set_nbxcfg:
movl $0x1, %eax
shll %cl, %eax
xorl %eax, %esi
/* side two */
movb $5, %bh
CALLSP(smbus_read_byte) /* number of physical banks */
@ -498,13 +651,15 @@ spd_set_nbxcfg:
ram_set_spd_registers:
CALL_LABEL(enable_smbus)
CALL_LABEL(setup_smbus)
CALL_LABEL(configure_sdramc)
CALL_LABEL(configure_rps_pgpol_drb)
CALL_LABEL(spd_set_drb)
CALL_LABEL(spd_set_dramc)
CALL_LABEL(spd_set_rps)
CALL_LABEL(configure_sdramc)
CALL_LABEL(spd_set_pgpol)
CALL_LABEL(spd_set_nbxcfg)
RET_LABEL(ram_set_spd_registers)
/* things that are not used */
#define FIRST_NORMAL_REFERENCE()

View file

@ -1,2 +1,5 @@
option CONFIG_ENABLE_MOUSE_IRQ12=1
option CONFIG_ENABLE_KBCCS=0
option CONFIG_SETUP_RTC=1
object southbridge.o
object smbus.o USE_PIIX4E_SMBUS

View file

@ -46,7 +46,7 @@ southbridge_fixup()
if (! pm_pcidev) {
printk_err("Can't find piix4e PM\n");
} else {
printk_debug("enabling smbus\n");
#if 0
smbus_io = NewPciIo(0x10);
@ -56,8 +56,8 @@ southbridge_fixup()
pci_write_config_dword(pm_pcidev, 0x90, smbus_io | 1); /* iobase addr */
pci_write_config_byte(pm_pcidev, 0xd2, (0x4 << 1) | 1); /* smbus enable */
pci_write_config_word(pm_pcidev, 0x4, 1); /* iospace enable */
printk_debug("enable pm functions\n");
#if 0
pm_io = NewPciIo(0x40);
@ -68,42 +68,100 @@ southbridge_fixup()
pci_write_config_byte(pm_pcidev, 0x80, 1); /* enable pm io address */
}
#if CONFIG_SETUP_RTC==1
printk_info( "Setting up RTC\n");
rtc_init(0);
#endif
printk_info("done.\n");
}
// Disables the secondary ide interface.
// This tri-states the signals on the seconday ide
// interface. Should free up the irq as well.
void disable_secondary_ide(void)
{
struct pci_dev *pcidev;
volatile unsigned char regval;
printk_info( "Disableing secondary ide controller\n");
pcidev = pci_find_device(0x8086, 0x7110, (void *)NULL);
pci_read_config_byte(pcidev, 0xb1, &regval);
regval &= 0xef;
pci_write_config_byte(pcidev, 0xb1, regval);
}
/*
This functions is now very misnamed as it deals with much more
than just the nvram
*/
void nvram_on()
{
/*; now set up PIIX4e registers 4e and 4f for nvram access.
; 4e will have value 0xc3, 4f will have value 2
; we are going to PIIX4 function 0; the PIIX4 is device 0x12.
; bit coding is 0x80000000 + 0x9000 (dev 0x12) + 0x4c (x4 aligned)
; plus 2 or 3 (e or f)
*/
/* well, this turns on the 1 MB, but we might as well enable APIC
/* well, this turns on the 1 MB, but we might as well enable APIC
* access too
*/
struct pci_dev *pcidev;
volatile unsigned char regval;
printk_info( "Enabling extended BIOS access...");
printk_info( "Enabling extended BIOS access\n");
pcidev = pci_find_device(0x8086, 0x7110, (void *)NULL);
if (pcidev) pci_write_config_word(pcidev, 0x4e, 0x03c3);
// Need to enable the full ISA bus rather than EIO which
// is enabled default
printk_info( "Enabling Full ISA Mode\n");
pci_read_config_byte(pcidev, 0xb0, &regval);
regval |= 0x01;
pci_write_config_byte(pcidev, 0xb0, regval);
// RAS 6/24/03
// Datasheet says if you enable the APIC then IRQ8 must
// not be setup as a GPI. Default is GPI so set this
// before eaabling the APIC
printk_info( "Enabling IRQ8\n");
pci_read_config_byte(pcidev, 0xb1, &regval);
regval |= 0x40;
pci_write_config_byte(pcidev, 0xb1, regval);
#if CONFIG_ENABLE_MOUSE_IRQ12==0
printk_info( "Disableing Mouse IRQ12 on piix4e\n");
if (pcidev) pci_write_config_word(pcidev, 0x4e, 0x03e1);
#else
printk_info( "Enabling Mouse IRQ12 on piix4e\n");
if (pcidev) pci_write_config_word(pcidev, 0x4e, 0x03f1);
#endif
printk_info("done.\n");
post_code(0x91);
}
// Have to talk to Eric Beiderman about this ...
// for now, I am putting in the old keyboard code, until we figure out
// for now, I am putting in the old keyboard code, until we figure out
// the best way to do this -- RGM
#ifdef NO_KEYBOARD
#if (NO_KEYBOARD==1)
void keyboard_on()
{
printk_debug( __FUNCTION__ ": Skipping Keyboard\n");
post_code(0x94);
}
#else
void keyboard_on()
{
u32 controlbits;
@ -115,15 +173,21 @@ void keyboard_on()
pcidev = pci_find_device(0x8086, 0x7110, (void *)NULL);
if (! pcidev) {
printk_err( __FUNCTION__ "Can't find dev 0x7110\n");
printk_err( __FUNCTION__ ": Can't find dev 0x7110\n");
return;
}
/* oh no, we are setting this below. Fix it later. */
/* to do -- changed these to PciReadByte */
// RAS 6/24/03
// If your super IO dosen't have IO decodeing of ports 60 and 64
// builtin then you need to enable this. Default is off since most
// superio don't need the extra help.
#if CONFIG_ENABLE_KBCCS == 1
pci_read_config_byte(pcidev, 0x4e, &regval);
printk_debug( __FUNCTION__ "regcal at 0x4e is 0x%x\n", regval);
printk_debug( __FUNCTION__ ": regcal at 0x4e is 0x%x\n", regval);
regval |= 0x2;
pci_write_config_byte(pcidev, 0x4e, regval);
#endif
/* this is a hole in the linux pci function design. You get devfn 0,
* but you can't select functions 1-3 using the pci_find_device!
@ -143,7 +207,15 @@ void keyboard_on()
pcibios_write_config_dword(0, devfn, 0x60, controlbits);
/* now keyboard should work, ha ha. */
pc_keyboard_init();
// RAS 6/24/03
// Me thinks that calling the keyboard init stuff here is incorrect
// since you may not have the keyboard _realley_ enabled yet if its in
// a superio. I've left it up to the superio code to call it
// but perhaps it should be a mainboard config item?
// pc_keyboard_init();
post_code(0x94);
}
#endif

View file

@ -0,0 +1 @@
option ENABLE_MOUSE=0

View file

@ -0,0 +1,50 @@
/*
* Enable the serial peripheral devices on the NSC Super IO chip PC87351
*/
/* The base address is 0x15c, 0x2e, depending on config bytes */
#define SIO_BASE $0x2e
#define SIO_INDEX SIO_BASE
#define SIO_DATA SIO_BASE+1
#define SIO_READ(ldn, index) \
mov SIO_BASE, %dx ; \
mov $0x07, %al ; \
outb %al, %dx ; \
inc %dx ; \
mov ldn, %al ; \
outb %al, %dx ; \
dec %dx ; \
mov index, %al ; \
outb %al, %dx ; \
inc %dx ; \
inb %dx, %al ;
#define SIO_WRITE(ldn, index, data) \
mov SIO_BASE, %dx ; \
mov $0x07, %al ; \
outb %al, %dx ; \
inc %dx ; \
mov ldn, %al ; \
outb %al, %dx ; \
dec %dx ; \
mov index, %al ; \
outb %al, %dx ; \
inc %dx ; \
mov data, %al ; \
outb %al, %dx ;
/* At boot up the chip is in configure mode so don't worry
* about getting it there just configure some peripherals.
*/
/* enable serial 1 Logical device 3 */
// the default address is 0x3f8
SIO_WRITE($0x03, $0x30, $0x01)
// enable serial 2 Logical device 2
// the default address is 0x2f8
SIO_WRITE($0x02, $0x30, $0x01)

View file

@ -0,0 +1,365 @@
/*
This is the superio config file for the National Semiconductor
pc87351 superio chip
*/
#include <pci.h>
#include <cpu/p5/io.h>
#include <serial_subr.h>
#include <printk.h>
// just define these here. We may never need them anywhere else
#define FLOPPY_DEVICE 0
#define PARALLEL_DEVICE 1
#define COM1_DEVICE 3
#define COM2_DEVICE 2
#define SYSTEM_WAKEUP_CONTROL 4
#define KBC_DEVICE 6
#define MOUSE_DEVICE 5
#define GPIO_DEVICE 7
#define FAN_SPEED_DEVICE 8
#define FLOPPY_DEFAULT_IOBASE 0x3f0
#define FLOPPY_DEFAULT_IRQ 6
#define FLOPPY_DEFAULT_DRQ 2
#define PARALLEL_DEFAULT_IOBASE 0x378
#define PARALLEL_DEFAULT_IRQ 7
#define PARALLEL_DEFAULT_DRQ 4 /* No dma */
#define COM1_DEFAULT_IOBASE 0x3f8
#define COM1_DEFAULT_IRQ 4
#define COM1_DEFAULT_BAUD 115200
#define COM2_DEFAULT_IOBASE 0x2f8
#define COM2_DEFAULT_IRQ 3
#define COM2_DEFAULT_BAUD 115200
#define KBC_DEFAULT_IOBASE0 0x60
#define KBC_DEFAULT_IOBASE1 0x64
#define KBC_DEFAULT_IRQ0 0x1
#define MOUSE_DEFAULT_IRQ0 0x0c
// funny how all these chips are "pnp compatible", and they're all different.
#define PNP_BASE_ADDR 0x2e
static void setup_devices(struct superio *sio);
struct superio_control superio_NSC_pc87351_control = {
pre_pci_init: (void *) 0,
init: setup_devices,
finishup: (void *) 0,
defaultport: PNP_BASE_ADDR,
name: "National Semiconductor pc87351"
};
void
enter_pnp(struct superio *sio)
{
// The 87351 dosen't seem to need this
// unlock it
/* outb(0x87, sio->port);
outb(0x87, sio->port);
*/
}
void
exit_pnp(struct superio *sio)
{
// The 87351 dosen't seem to need this
/* all done. */
// select configure control
/*
outb(0xaa, sio->port);
*/
}
static void write_config(struct superio *sio,
unsigned char value, unsigned char reg)
{
outb(reg, sio->port);
outb(value, sio->port +1);
}
static unsigned char read_config(struct superio *sio, unsigned char reg)
{
outb(reg, sio->port);
return inb(sio->port +1);
}
static void set_logical_device(struct superio *sio, int device)
{
write_config(sio, device, 0x07);
}
static void set_irq0(struct superio *sio, unsigned irq)
{
write_config(sio, irq, 0x70);
}
static void set_irq1(struct superio *sio, unsigned irq)
{
write_config(sio, irq, 0x72);
}
static void set_drq(struct superio *sio, unsigned drq)
{
write_config(sio, drq & 0xff, 0x74);
}
static void set_iobase0(struct superio *sio, unsigned iobase)
{
write_config(sio, (iobase >> 8) & 0xff, 0x60);
write_config(sio, iobase & 0xff, 0x61);
}
static void set_iobase1(struct superio *sio, unsigned iobase)
{
write_config(sio, (iobase >> 8) & 0xff, 0x62);
write_config(sio, iobase & 0xff, 0x63);
}
static void set_enable(struct superio *sio, int enable)
{
write_config(sio, enable?0x1:0x0, 0x30);
#if 1
if (enable) {
printk_debug("enabled superio device: %d\n",
read_config(sio, 0x07));
}
#endif
}
static void set_mux_pins(struct superio *sio, unsigned char val)
{
write_config(sio,val,0x22);
}
static void set_conf3(struct superio *sio, unsigned char val)
{
write_config(sio,val,0x23);
}
static void setup_parallel(struct superio *sio)
{
/* Remember the default resources */
unsigned iobase = PARALLEL_DEFAULT_IOBASE;
unsigned irq = PARALLEL_DEFAULT_IRQ;
unsigned drq = PARALLEL_DEFAULT_DRQ;
/* Select the device */
set_logical_device(sio, PARALLEL_DEVICE);
/* Disable it while initializing */
set_enable(sio, 0);
if (sio->lpt) {
set_iobase0(sio, iobase);
set_irq0(sio, irq);
set_drq(sio, drq);
set_enable(sio, 1);
}
}
// test a non-fifo uart init. Stupid chip.
/* Line Control Settings */
#ifndef TTYS0_LCS
/* Set 8bit, 1 stop bit, no parity */
#define TTYS0_LCS 0x3
#endif
#define UART_LCS TTYS0_LCS
/* Data */
#define UART_RBR 0x00
#define UART_TBR 0x00
/* Control */
#define UART_IER 0x01
#define UART_IIR 0x02
#define UART_FCR 0x02
#define UART_LCR 0x03
#define UART_MCR 0x04
#define UART_DLL 0x00
#define UART_DLM 0x01
/* Status */
#define UART_LSR 0x05
#define UART_MSR 0x06
#define UART_SCR 0x07
inline void uart_init_nofifo(unsigned base_port, unsigned divisor)
{
/* disable interrupts */
outb(0x0, base_port + UART_IER);
#if 0
/* enable fifo's */
outb(0x01, base_port + UART_FCR);
#else
outb(0x06, base_port + UART_FCR);
#endif
/* Set Baud Rate Divisor to 12 ==> 115200 Baud */
outb(0x80 | UART_LCS, base_port + UART_LCR);
outb(divisor & 0xFF, base_port + UART_DLL);
outb((divisor >> 8) & 0xFF, base_port + UART_DLM);
outb(UART_LCS, base_port + UART_LCR);
}
static void setup_com(struct superio *sio,
struct com_ports *com, int device)
{
// set baud, default to 115200 if not set.
int divisor = 115200/(com->baud ? com->baud : 1);
printk_debug("%s com device: %02x\n",
com->enable? "Enabling" : "Disabling", device);
/* Select the device */
set_logical_device(sio, device);
/* Disable it while it is initialized */
set_enable(sio, 0);
if (com->enable) {
printk_debug(" iobase = 0x%04x irq=%d\n",
com->base, com->irq);
set_iobase0(sio, com->base);
set_irq0(sio, com->irq);
/* We are initialized so enable the device */
set_enable(sio, 1);
/* Now initialize the com port */
uart_init(com->base, divisor);
}
}
static void setup_floppy(struct superio *sio)
{
/* Remember the default resources */
unsigned iobase = FLOPPY_DEFAULT_IOBASE;
unsigned irq = FLOPPY_DEFAULT_IRQ;
unsigned drq = FLOPPY_DEFAULT_DRQ;
/* Select the device */
set_logical_device(sio, FLOPPY_DEVICE);
/* Disable it while initializing */
set_enable(sio, 0);
if (sio->floppy) {
set_iobase0(sio, iobase);
set_irq0(sio, irq);
set_drq(sio, drq);
set_enable(sio, 1);
}
}
#if NO_KEYBOARD==0
void pc_keyboard_init();
static void setup_keyboard(struct superio *sio)
{
/* Remember the default resources */
unsigned iobase0 = KBC_DEFAULT_IOBASE0;
unsigned iobase1 = KBC_DEFAULT_IOBASE1;
unsigned irq0 = KBC_DEFAULT_IRQ0;
/* Select the device */
set_logical_device(sio, KBC_DEVICE);
/* Disable it while initializing */
set_enable(sio, 0);
if (sio->keyboard) {
set_iobase0(sio, iobase0);
set_iobase1(sio, iobase1);
set_irq0(sio, irq0);
set_enable(sio, 1);
/* Initialize the keyboard */
pc_keyboard_init();
}
}
#endif
#if ENABLE_MOUSE==1
static void setup_mouse(struct superio *sio)
{
/* Remember the default resources */
unsigned irq0 = MOUSE_DEFAULT_IRQ0;
/* Select the device */
set_logical_device(sio, MOUSE_DEVICE);
/* Disable it while initializing */
set_enable(sio, 0);
if (sio->mouse) {
set_irq0(sio, irq0);
set_enable(sio, 1);
}
}
#endif
static void setup_devices(struct superio *sio)
{
if (sio->port == 0) {
sio->port = sio->super->defaultport;
}
if (sio->com1.base == 0) sio->com1.base = COM1_DEFAULT_IOBASE;
if (sio->com1.irq == 0) sio->com1.irq = COM1_DEFAULT_IRQ;
if (sio->com1.baud == 0) sio->com1.baud = COM1_DEFAULT_BAUD;
if (sio->com2.base == 0) sio->com2.base = COM2_DEFAULT_IOBASE;
if (sio->com2.irq == 0) sio->com2.irq = COM2_DEFAULT_IRQ;
if (sio->com2.baud == 0) sio->com2.baud = COM2_DEFAULT_BAUD;
enter_pnp(sio);
/* setup pins to be IRQ1, 3-7 and 12.
Default is to enable PCICLK and SERIRQ and GPIO.
Bits7-1 = Default;
Bit0 = 0; Default = 1;
*/
set_mux_pins(sio,0xa0);
/* setup more pin mux options */
set_conf3(sio,0x01);
/* enable/disable floppy */
setup_floppy(sio);
/* enable or disable parallel */
setup_parallel(sio);
/* enable/disable com1 */
setup_com(sio, &sio->com1, COM1_DEVICE);
/* enable/disable com2 */
setup_com(sio, &sio->com2, COM2_DEVICE);
#if ENABLE_MOUSE==1
setup_mouse(sio);
#endif
#if NO_KEYBOARD==0
/* enable/disable keyboard */
setup_keyboard(sio);
#endif
/* // gpio_port2
set_logical_device(sio, GPIO_PORT2_DEVICE);
set_enable(sio, sio->gpio2);
// gpio_port3
set_logical_device(sio, GPIO_PORT3_DEVICE);
set_enable(sio, sio->gpio3);
*/
exit_pnp(sio);
}
#ifndef USE_NEW_SUPERIO_INTERFACE
// this must die soon.
void
final_superio_fixup()
{
/*
static struct superio temp = { &superio_NSC_pc87351_control,
.com1={1}, .floppy=1};
finishup(&temp);
enable_com(PNP_COM1_DEVICE);
enable_com(PNP_COM2_DEVICE);
exit_pnp();
*/
}
#endif

View file

@ -0,0 +1,54 @@
target src
mainboard bitworks/ims
option CONFIGURE_L2_CACHE=1
option ENABLE_FIXED_AND_VARIABLE_MTRRS=1
option SERIAL_CONSOLE=1
option DEFAULT_CONSOLE_LEVEL=9
option MAXIMUM_CONSOLE_LOGLEVEL=9
option RAMTEST=0
#option ROM_IMAGE_SIZE=327680
#option ROM_IMAGE_SIZE=393216
option NO_KEYBOARD=0
option ENABLE_MOUSE=1
# This option controls if the Native IDE code attempts to run
option BOOT_IDE=0
option CONFIG_COMPRESS=0
option USE_GENERIC_ROM=1
option USE_ELF_BOOT=1
option CONFIG_ASSIGNIRQ=1
# Etherboot IDE driver
#option PAYLOAD_SIZE=32768
#payload /bitworks/src/etherboot-5.1.8/src/bin/ide_disk.zelf
# ADLO
# linuxbios rom size. Should be 512k-*actual* size of payload
option ROM_IMAGE_SIZE=360448
# remember this is not absolute but just the dd bs=parameter
# so it can be larger than what you have specified
#
option PAYLOAD_SIZE=32768
payload /bitworks/src/freebios/util/ADLO/payload
# Memtest size is larger than I need but I like powers of 2
#option PAYLOAD_SIZE=131072
#payload /bitworks/src/memtest86-3.0/memtest
#option VIDEO_CONSOLE=1
#option CONFIG_PCIBIOS=1
#option CONFIG_VGABIOS=1
#option CONFIG_REALMODE_IDT=1
#option CONFIG_ENABLE_MOUSE_IRQ12=1
makerule tonet: linuxbios.rom ;
addaction romimage ./2net