mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
- Updates for the supermicro p4dc6 motherboard
- Code to initialize sdram from C on the l440gx - cache as ram code fro the p6 it works except conflict misses occur with addresses that are not cached so writing to ram does not work. Which makes it to brittle to count on. - Initial implementation of a fallback booting scheme where we can have two copies of linuxbios in rom at once. - Movement of 32 bit entry code from entry16.inc to entry32.inc - Update of all config files so they now also include entry32.inc - Fix for start_stop.c & entry16.inc so I can fairly arbitrarily relocate the 16bit entry code in SMP. - A small number of fixes for warnings
This commit is contained in:
parent
0ddd8a6f16
commit
2beb0a1bcc
97 changed files with 2518 additions and 292 deletions
|
@ -5,9 +5,20 @@
|
|||
#define CACHE_RAM_BASE 0
|
||||
#endif
|
||||
|
||||
#if !defined(ASSEMBLY)
|
||||
#define CACHE_RAM_SEG_BASE (((unsigned long)CACHE_RAM_BASE) - ((unsigned long)_RAMBASE))
|
||||
#else
|
||||
#define CACHE_RAM_SEG_BASE (CACHE_RAM_BASE - _RAMBASE)
|
||||
#endif
|
||||
|
||||
#define RAM(type, addr) (*((type *)((unsigned char*)((addr) - CACHE_RAM_SEG_BASE))))
|
||||
#define RAM_ADDR( addr) ((void *)((addr) - CACHE_RAM_BASE))
|
||||
|
||||
|
||||
#if !defined(ASSEMBLY)
|
||||
|
||||
#define RAM_ADDR( addr) ((void *)(((unsigned char *)(addr)) - CACHE_RAM_SEG_BASE))
|
||||
#define RAM(type, addr) (*((volatile type *)RAM_ADDR(addr)))
|
||||
|
||||
void cache_ram_start(void);
|
||||
#endif
|
||||
|
||||
#endif /* CACHE_RAM_H */
|
||||
|
|
20
src/arch/i386/include/bitops.h
Normal file
20
src/arch/i386/include/bitops.h
Normal file
|
@ -0,0 +1,20 @@
|
|||
#ifndef I386_BITOPS_H
|
||||
#define I386_BITOPS_H
|
||||
|
||||
/**
|
||||
* log2 - Find the truncated log base 2 of x
|
||||
*/
|
||||
|
||||
static inline unsigned long log2(unsigned long x)
|
||||
{
|
||||
unsigned long r = 0;
|
||||
__asm__(
|
||||
"bsrl %1, %0\n\t"
|
||||
"jnz 1f\n\t"
|
||||
"movl $-1, %0\n\t"
|
||||
"1:\n\t"
|
||||
: "=r" (r) : "g" (x));
|
||||
return r;
|
||||
|
||||
}
|
||||
#endif /* I386_BITOPS_H */
|
|
@ -6,7 +6,7 @@ jmp cpu_reset_out
|
|||
|
||||
.section ".rodata"
|
||||
|
||||
#if ASM_CONSOLE_LOGLEVEL >= BIOS_DEBUG
|
||||
#if ASM_CONSOLE_LOGLEVEL >= BIOS_SPEW
|
||||
cpu_reset_str: .string "cpu_reset\r\n";
|
||||
cpu_apic_str: .string "apic: ";
|
||||
cpu_size_set_str: .string "cpu memory size set\r\n";
|
||||
|
@ -16,7 +16,7 @@ cpu_size_set_str: .string "cpu memory size set\r\n";
|
|||
.text
|
||||
|
||||
__cpu_reset:
|
||||
CONSOLE_DEBUG_TX_STRING($cpu_reset_str)
|
||||
CONSOLE_SPEW_TX_STRING($cpu_reset_str)
|
||||
|
||||
#ifdef SMP
|
||||
/* Enable the local apic, and map it where we expext it */
|
||||
|
@ -32,15 +32,15 @@ __cpu_reset:
|
|||
movl (APIC_ID + APIC_DEFAULT_BASE), %edi
|
||||
shrl $24, %edi
|
||||
|
||||
CONSOLE_DEBUG_TX_STRING($cpu_apic_str)
|
||||
CONSOLE_DEBUG_TX_HEX32(%edi)
|
||||
CONSOLE_DEBUG_TX_CHAR($'\r')
|
||||
CONSOLE_DEBUG_TX_CHAR($'\n')
|
||||
CONSOLE_SPEW_TX_STRING($cpu_apic_str)
|
||||
CONSOLE_SPEW_TX_HEX32(%edi)
|
||||
CONSOLE_SPEW_TX_CHAR($'\r')
|
||||
CONSOLE_SPEW_TX_CHAR($'\n')
|
||||
#endif
|
||||
|
||||
CALLSP(set_memory_size)
|
||||
|
||||
CONSOLE_DEBUG_TX_STRING($cpu_size_set_str);
|
||||
CONSOLE_SPEW_TX_STRING($cpu_size_set_str);
|
||||
|
||||
#ifdef SMP
|
||||
/* Test to see if we are the boot strap processor.
|
||||
|
|
1
src/arch/i386/lib/failover.lds
Normal file
1
src/arch/i386/lib/failover.lds
Normal file
|
@ -0,0 +1 @@
|
|||
__normal_image = (ZKERNEL_START & 0xfffffff0) - 8;
|
|
@ -49,6 +49,7 @@ static char rcsid[] = "$Id$";
|
|||
#include <part/floppy.h>
|
||||
#include <part/sizeram.h>
|
||||
#include <part/hard_reset.h>
|
||||
#include <part/fallback_boot.h>
|
||||
#include <arch/ioapic.h>
|
||||
#include <pc80/i8259.h>
|
||||
#include <pc80/keyboard.h>
|
||||
|
@ -289,6 +290,9 @@ void hardwaremain(int boot_complete)
|
|||
post_code(0x96);
|
||||
write_smp_table((void *)16, processor_map);
|
||||
|
||||
/* Reset to booting from this image as late as possible */
|
||||
boot_successful();
|
||||
|
||||
#ifdef LINUXBIOS
|
||||
printk_info("Jumping to linuxbiosmain()...\n");
|
||||
// we could go to argc, argv, for main but it seems like overkill.
|
||||
|
|
9
src/arch/i386/lib/noop_failover.inc
Normal file
9
src/arch/i386/lib/noop_failover.inc
Normal file
|
@ -0,0 +1,9 @@
|
|||
/* Step 1: Test for cpu reset
|
||||
* That is, did I just boot or is this a later boot since power on.
|
||||
* The result of this test in %al
|
||||
* %al == 1 -- We are rebooting
|
||||
* %al == 0 -- This is the initial boot
|
||||
*
|
||||
*/
|
||||
testb %al, %al
|
||||
jnz __cpu_reset
|
|
@ -1,6 +1,7 @@
|
|||
#include <printk.h>
|
||||
#include <pci.h>
|
||||
#include <arch/pirq_routing.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
void check_pirq_routing_table(void)
|
||||
|
|
|
@ -4,7 +4,12 @@
|
|||
#include <delay.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#ifndef START_CPU_SEG
|
||||
#define START_CPU_SEG 0x90000
|
||||
#endif
|
||||
#if (START_CPU_SEG&0xffff) != 0
|
||||
#error START_CPU_SEG must be 64k aligned
|
||||
#endif
|
||||
|
||||
static inline void hlt(void)
|
||||
{
|
||||
|
@ -142,13 +147,13 @@ int start_cpu(unsigned long apicid)
|
|||
return 0;
|
||||
}
|
||||
|
||||
start_eip = 0x90000 + (((unsigned long)_start) & 0xf000);
|
||||
start_eip = START_CPU_SEG + (((unsigned long)_start) & 0xf000);
|
||||
if ((((unsigned long)_start) & 0xfff) != 0) {
|
||||
printk_err("_start is not 4K aligned!\n");
|
||||
return 0;
|
||||
}
|
||||
memcpy((void *)start_eip, _start, _estart - _start);
|
||||
printk_spew("start eip=0x%08lx\n", start_eip);
|
||||
printk_spew("start_eip=0x%08lx\n", start_eip);
|
||||
|
||||
num_starts = 2;
|
||||
|
||||
|
@ -160,7 +165,7 @@ int start_cpu(unsigned long apicid)
|
|||
maxlvt = 4;
|
||||
|
||||
for (j = 1; j <= num_starts; j++) {
|
||||
printk_spew("Sending STARTUP #%d.\n",j);
|
||||
printk_spew("Sending STARTUP #%d to %u.\n", j, apicid);
|
||||
apic_read_around(APIC_SPIV);
|
||||
apic_write(APIC_ESR, 0);
|
||||
apic_read(APIC_ESR);
|
||||
|
|
|
@ -25,8 +25,6 @@ it with the version available from LANL.
|
|||
* protected mode.
|
||||
*/
|
||||
|
||||
#include <arch/cache_ram.h>
|
||||
|
||||
.text
|
||||
.code16
|
||||
.globl EXT(_start)
|
||||
|
@ -41,8 +39,8 @@ EXT(_start):
|
|||
/* any further code. Even though paging is disabled we could still get*/
|
||||
/*false address translations due to the TLB if we didn't invalidate it.*/
|
||||
/**/
|
||||
xor %eax, %eax
|
||||
mov %eax, %cr3 /* Invalidate TLB*/
|
||||
xorl %eax, %eax
|
||||
movl %eax, %cr3 /* Invalidate TLB*/
|
||||
|
||||
/* invalidate the cache */
|
||||
invd
|
||||
|
@ -66,18 +64,28 @@ EXT(_start):
|
|||
* So while this code is relocateable it isn't arbitrarily
|
||||
* relocatable.
|
||||
*
|
||||
* In particular this code can be run with the base address of
|
||||
* the code segment at either 0xffff0000 or 0xf0000.
|
||||
* The first is what is initiallly loaded when the processor
|
||||
* powers on. The second is normal real mode segment 0xf000.
|
||||
* The criteria for relocation have been relaxed to their
|
||||
* utmost, so that we can use the same code for both
|
||||
* our initial entry point and startup of the second cpu.
|
||||
* The code assumes when executing at _start that:
|
||||
* (((cs & 0xfff) == 0) and (ip == _start & 0xffff))
|
||||
* or
|
||||
* ((cs == anything) and (ip == 0)).
|
||||
*
|
||||
* At this point all the linker script does when calculating
|
||||
* gdtptr_offset is return the low 16 bits so your segment
|
||||
* must be 64K aligned. So it wouldn't be too much work
|
||||
* to support other segments, I just don't see the point
|
||||
* right now.
|
||||
* The restrictions in reset16.inc mean that _start initially
|
||||
* must be loaded at or above 0xffff0000 or below 0x100000.
|
||||
*
|
||||
* The linker scripts computs gdtptr16_offset by simply returning
|
||||
* the low 16 bits. This means that the intial segment used
|
||||
* when start is called must be 64K aligned. This should not
|
||||
* restrict the address as the ip address can be anything.
|
||||
*/
|
||||
data32 lgdt %cs:EXT(gdtptr_offset)
|
||||
|
||||
movw %cs, %ax
|
||||
shlw $4, %ax
|
||||
movw $EXT(gdtptr16_offset), %bx
|
||||
subw %ax, %bx
|
||||
data32 lgdt %cs:(%bx)
|
||||
|
||||
movl %cr0, %eax
|
||||
andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */
|
||||
|
@ -85,62 +93,19 @@ EXT(_start):
|
|||
movl %eax, %cr0
|
||||
|
||||
/* Now that we are in protected mode jump to a 32 bit code segment. */
|
||||
data32 ljmp $0x10, $_protected_start
|
||||
data32 ljmp $0x10, $__protected_start
|
||||
|
||||
|
||||
/** This gdt has a 4 Gb code segment at 0x10, and a 4 GB data segment
|
||||
/** The gdt has a 4 Gb code segment at 0x10, and a 4 GB data segment
|
||||
* at 0x18; these are Linux-compatible.
|
||||
*/
|
||||
|
||||
|
||||
/** GDT. we have modified this from the original freebios to make it
|
||||
* compatible with linux. This puts text at seg 0x10 and data at 0x18
|
||||
*/
|
||||
.align 4
|
||||
.globl EXT(gdtptr)
|
||||
EXT(gdtptr):
|
||||
.globl EXT(gdtptr16)
|
||||
EXT(gdtptr16):
|
||||
.word 4*8-1
|
||||
.long gdt /* we know the offset */
|
||||
|
||||
.globl EXT(_estart)
|
||||
EXT(_estart):
|
||||
|
||||
gdt:
|
||||
.word 0x0000, 0x0000 /* dummy */
|
||||
.byte 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
.word 0xffff, (CACHE_RAM_SEG_BASE & 0xffff) /* flat offset data segment */
|
||||
.byte ((CACHE_RAM_SEG_BASE >> 16)& 0xff), 0x93, 0xcf
|
||||
.byte ((CACHE_RAM_SEG_BASE >> 24) & 0xff)
|
||||
|
||||
.word 0xffff, 0x0000 /* flat code segment */
|
||||
.byte 0x00, 0x9b, 0xcf, 0x00
|
||||
|
||||
.word 0xffff, 0x0000 /* flat data segment */
|
||||
.byte 0x00, 0x93, 0xcf, 0x00
|
||||
|
||||
|
||||
/*
|
||||
* When we come here we are in protected mode. We expand
|
||||
* the stack and copies the data segment from ROM to the
|
||||
* memory.
|
||||
*
|
||||
* After that, we call the chipset bootstrap routine that
|
||||
* does what is left of the chipset initialization.
|
||||
*
|
||||
* NOTE aligned to 4 so that we are sure that the prefetch
|
||||
* cache will be reloaded.
|
||||
*/
|
||||
.align 4
|
||||
_protected_start:
|
||||
.code32
|
||||
intel_chip_post_macro(0x10) /* post 10 */
|
||||
|
||||
movw $0x18, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
gdtptr_offset = gdtptr & 0xffff;
|
||||
gdtptr16_offset = gdtptr16 & 0xffff;
|
||||
_start_offset = _start & 0xffff;
|
||||
|
|
|
@ -1,5 +1,63 @@
|
|||
/* For starting linuxBIOS in protected mode */
|
||||
/* For starting linuxBIOS in protected mode */
|
||||
|
||||
#include <arch/cache_ram.h>
|
||||
|
||||
.text
|
||||
.align 4
|
||||
.code32
|
||||
|
||||
/** This gdt has a 4 Gb code segment at 0x10, and a 4 GB data segment
|
||||
* at 0x18; these are Linux-compatible.
|
||||
*/
|
||||
|
||||
/** GDT. we have modified this from the original freebios to make it
|
||||
* compatible with linux. This puts text at seg 0x10 and data at 0x18
|
||||
*/
|
||||
|
||||
.align 4
|
||||
.globl EXT(gdtptr)
|
||||
EXT(gdtptr):
|
||||
.word 4*8-1
|
||||
.long gdt /* we know the offset */
|
||||
|
||||
gdt:
|
||||
.word 0x0000, 0x0000 /* dummy */
|
||||
.byte 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
.word 0xffff, (CACHE_RAM_SEG_BASE & 0xffff) /* flat offset data segment */
|
||||
.byte ((CACHE_RAM_SEG_BASE >> 16)& 0xff), 0x93, 0xcf
|
||||
.byte ((CACHE_RAM_SEG_BASE >> 24) & 0xff)
|
||||
|
||||
.word 0xffff, 0x0000 /* flat code segment */
|
||||
.byte 0x00, 0x9b, 0xcf, 0x00
|
||||
|
||||
.word 0xffff, 0x0000 /* flat data segment */
|
||||
.byte 0x00, 0x93, 0xcf, 0x00
|
||||
|
||||
/*
|
||||
* When we come here we are in protected mode. We expand
|
||||
* the stack and copies the data segment from ROM to the
|
||||
* memory.
|
||||
*
|
||||
* After that, we call the chipset bootstrap routine that
|
||||
* does what is left of the chipset initialization.
|
||||
*
|
||||
* NOTE aligned to 4 so that we are sure that the prefetch
|
||||
* cache will be reloaded.
|
||||
*/
|
||||
.align 4
|
||||
.globl EXT(protected_start)
|
||||
EXT(protected_start):
|
||||
|
||||
lgdt %cs:gdtptr
|
||||
ljmp $0x10, $__protected_start
|
||||
|
||||
__protected_start:
|
||||
intel_chip_post_macro(0x10) /* post 10 */
|
||||
|
||||
movw $0x18, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
|
|
|
@ -20,5 +20,8 @@ EXT(reset_vector):
|
|||
#error _ROMBASE is an unsupported value
|
||||
#endif
|
||||
|
||||
. = 0x8;
|
||||
.code32
|
||||
jmp EXT(protected_start)
|
||||
|
||||
.previous
|
||||
|
|
10
src/cpu/i386/reset32.inc
Normal file
10
src/cpu/i386/reset32.inc
Normal file
|
@ -0,0 +1,10 @@
|
|||
.section ".reset"
|
||||
.code16
|
||||
.globl EXT(reset_vector)
|
||||
EXT(reset_vector):
|
||||
|
||||
. = 0x8;
|
||||
.code32
|
||||
jmp EXT(protected_start)
|
||||
|
||||
.previous
|
14
src/cpu/i386/reset32.lds
Normal file
14
src/cpu/i386/reset32.lds
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* _ROMTOP : The top of the rom used where we
|
||||
* need to put the reset vector.
|
||||
*/
|
||||
|
||||
SECTIONS {
|
||||
_ROMTOP = _ROMBASE + ROM_IMAGE_SIZE - 0x10;
|
||||
. = _ROMTOP;
|
||||
.reset (.): {
|
||||
*(.reset)
|
||||
. = 15 ;
|
||||
BYTE(0x00);
|
||||
}
|
||||
}
|
|
@ -44,4 +44,4 @@
|
|||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
#endif
|
||||
#endif
|
||||
|
|
40
src/cpu/p6/cache_ram_fini.inc
Normal file
40
src/cpu/p6/cache_ram_fini.inc
Normal file
|
@ -0,0 +1,40 @@
|
|||
#if defined(CACHE_RAM_BASE) && defined(CACHE_RAM_SIZE)
|
||||
/* Note: We cannot be running from simulated ram in
|
||||
* this code. If we are evil things will happen.
|
||||
*/
|
||||
|
||||
/* Disable the cache */
|
||||
movl %cr0, %eax
|
||||
orl $0x40000000, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Flush everything that is left in the cache,
|
||||
* We don't want random writes to memory to occur later on.
|
||||
*/
|
||||
invd
|
||||
|
||||
/* Disable the cache ram mtrr */
|
||||
movl $0x204, %ecx
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
|
||||
movl $0x205, %ecx
|
||||
xorl %eax, %eax
|
||||
xorl %edx, %edx
|
||||
wrmsr
|
||||
|
||||
/* Reenable the cache now that the mtrr is cleared */
|
||||
movl %cr0, %eax
|
||||
andl $0x9fffffff, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Reload the normal data segments */
|
||||
movw $0x18, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
movw %ax, %fs
|
||||
movw %ax, %gs
|
||||
|
||||
#endif
|
48
src/cpu/p6/cache_ram_init.inc
Normal file
48
src/cpu/p6/cache_ram_init.inc
Normal file
|
@ -0,0 +1,48 @@
|
|||
#if defined(CACHE_RAM_BASE) && defined(CACHE_RAM_SIZE)
|
||||
/* Disable the cache while we set up the cache ram MTRR */
|
||||
movl %cr0, %eax
|
||||
orl $0x40000000, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Set up an mtrr in write-back mode over some arbitrary
|
||||
* location. As long as we do not get a capacity miss,
|
||||
* or a multiprocessor conflict miss this should allow us to
|
||||
* function as if we have memory even when it hasn't been
|
||||
* enabled yet.
|
||||
*/
|
||||
movl $0x204, %ecx /* mtrr[0] physical base register */
|
||||
xorl %edx, %edx
|
||||
movl $(CACHE_RAM_BASE | 0x006), %eax
|
||||
wrmsr
|
||||
|
||||
movl $0x205, %ecx /* mtrr[0] physical mask register */
|
||||
movl $0x0000000f, %edx
|
||||
movl $(~(CACHE_RAM_SIZE - 1) | 0x800), %eax
|
||||
wrmsr
|
||||
|
||||
/* Reenable the cache now that the mtrr is set up */
|
||||
movl %cr0, %eax
|
||||
andl $0x9fffffff, %eax
|
||||
movl %eax, %cr0
|
||||
|
||||
/* Force cache ram area into cache
|
||||
* Note: Some versions of the P4 don't allocate a cache
|
||||
* line on write immediately after a mtrr change, so
|
||||
* we make certain we read the address before we write
|
||||
* to it.
|
||||
*/
|
||||
movl $CACHE_RAM_BASE, %esi
|
||||
movl $(CACHE_RAM_BASE + CACHE_RAM_SIZE), %edi
|
||||
1:
|
||||
movl (%esi), %eax
|
||||
addl $4, %esi
|
||||
movl %eax, -4(%esi)
|
||||
cmpl %esi, %edi
|
||||
jnz 1b
|
||||
|
||||
/* Load a different set of data segments */
|
||||
movw $0x08, %ax
|
||||
movw %ax, %ds
|
||||
movw %ax, %es
|
||||
movw %ax, %ss
|
||||
#endif
|
27
src/cpu/p6/cache_ram_start.inc
Normal file
27
src/cpu/p6/cache_ram_start.inc
Normal file
|
@ -0,0 +1,27 @@
|
|||
#include <arch/cache_ram.h>
|
||||
|
||||
/* copy data segment from FLASH ROM to CACHE */
|
||||
movl $(EXT(_ldata) - CACHE_RAM_SEG_BASE), %esi
|
||||
movl $EXT(_data), %edi
|
||||
movl $(EXT(_eldata) - CACHE_RAM_SEG_BASE), %ecx
|
||||
subl %esi, %ecx
|
||||
jz 1f /* should not happen */
|
||||
rep
|
||||
movsb
|
||||
1:
|
||||
|
||||
/** clear bss */
|
||||
movl $EXT(_bss), %edi
|
||||
movl $EXT(_ebss), %ecx
|
||||
subl %edi, %ecx
|
||||
jz 1f
|
||||
xorl %eax, %eax
|
||||
rep
|
||||
stosb
|
||||
1:
|
||||
|
||||
/* set new stack */
|
||||
movl $(_stack + STACK_SIZE), %esp
|
||||
|
||||
call cache_ram_start
|
||||
|
|
@ -225,6 +225,42 @@ static void intel_set_var_mtrr(unsigned int reg, unsigned long base, unsigned lo
|
|||
|
||||
}
|
||||
|
||||
/* setting variable mtrr, comes from linux kernel source */
|
||||
void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsigned char type)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
if (reg >= 8)
|
||||
return;
|
||||
|
||||
// it is recommended that we disable and enable cache when we
|
||||
// do this.
|
||||
/* Disable cache */
|
||||
/* Write back the cache and flush TLB */
|
||||
asm volatile (
|
||||
"movl %%cr0, %0\n\t"
|
||||
"orl $0x40000000, %0\n\t"
|
||||
"movl %0, %%cr0\n\t"
|
||||
:"=r" (tmp)
|
||||
::"memory");
|
||||
|
||||
if (size == 0) {
|
||||
/* The invalid bit is kept in the mask, so we simply clear the
|
||||
relevant mask register to disable a range. */
|
||||
wrmsr (MTRRphysMask_MSR (reg), 0, 0);
|
||||
} else {
|
||||
/* Bit 32-35 of MTRRphysMask should be set to 1 */
|
||||
wrmsr (MTRRphysBase_MSR (reg), base | type, 0);
|
||||
wrmsr (MTRRphysMask_MSR (reg), ~(size - 1) | 0x800, 0x0F);
|
||||
}
|
||||
|
||||
// turn cache back on.
|
||||
asm volatile ("movl %%cr0, %0\n\t"
|
||||
"andl $0x9fffffff, %0\n\t"
|
||||
"movl %0, %%cr0\n\t":"=r" (tmp)::"memory");
|
||||
|
||||
}
|
||||
|
||||
/* fms: find most sigificant bit set, stolen from Linux Kernel Source. */
|
||||
static __inline__ unsigned int fms(unsigned int x)
|
||||
{
|
||||
|
|
55
src/include/cpu/i786/multiplier.h
Normal file
55
src/include/cpu/i786/multiplier.h
Normal file
|
@ -0,0 +1,55 @@
|
|||
|
||||
/*
|
||||
** NMI A20M IGNNE INTR
|
||||
* X8 H H H H
|
||||
* X9 H H H L projected
|
||||
* X10 H H L H
|
||||
* X11 H H L L
|
||||
* X12 H L H H
|
||||
* X13 H L H L
|
||||
* X14 H L L H
|
||||
* X15 H L L L
|
||||
* X16 L H H H
|
||||
* X17 L H H L
|
||||
* X18 L H L H
|
||||
* X19 L H L L
|
||||
* X20 L L H H
|
||||
* X21 L L H L projected
|
||||
* X22 L L L H projected
|
||||
* X23 L L L L projected
|
||||
*
|
||||
** NMI INTR IGNNE A20M
|
||||
* X8 H H H H
|
||||
* X9 H L H H projected
|
||||
* X10 H H L H
|
||||
* X11 H L L H
|
||||
* X12 H H H L
|
||||
* X13 H L H L
|
||||
* X14 H H L L
|
||||
* X15 H L L L
|
||||
* X16 L H H H
|
||||
* X17 L L H H
|
||||
* X18 L H L H
|
||||
* X19 L L L H
|
||||
* X20 L H H L
|
||||
* X21 L L H L projected
|
||||
* X22 L H L L projected
|
||||
* X23 L L L L projected
|
||||
*/
|
||||
|
||||
#define XEON_X8 0xf
|
||||
#define XEON_X9 0xb /* projected */
|
||||
#define XEON_X10 0xd
|
||||
#define XEON_X11 0x9
|
||||
#define XEON_X12 0xe
|
||||
#define XEON_X13 0xa
|
||||
#define XEON_X14 0xc
|
||||
#define XEON_X15 0x8
|
||||
#define XEON_X16 0x7
|
||||
#define XEON_X17 0x3
|
||||
#define XEON_X18 0x5
|
||||
#define XEON_X19 0x1
|
||||
#define XEON_X20 0x6
|
||||
#define XEON_X21 0x2 /* projected */
|
||||
#define XEON_X22 0x4 /* projected */
|
||||
#define XEON_X23 0x0 /* projected */
|
|
@ -33,6 +33,7 @@
|
|||
|
||||
#if !defined(ASSEMBLY)
|
||||
|
||||
void set_var_mtrr(unsigned int reg, unsigned long base, unsigned long size, unsigned char type);
|
||||
#if defined(INTEL_PPRO_MTRR)
|
||||
void setup_mtrrs(unsigned long ramsizeK);
|
||||
#endif
|
||||
|
|
|
@ -7,6 +7,10 @@
|
|||
#define MAXIMUM_CONSOLE_LOGLEVEL 8
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_CONSOLE_LOGLEVEL
|
||||
#define DEFAULT_CONSOLE_LOGLEVEL 8 /* anything MORE serious than BIOS_SPEW */
|
||||
#endif
|
||||
|
||||
#if (DEFAULT_CONSOLE_LOGLEVEL <= MAXIMUM_CONSOLE_LOGLEVEL)
|
||||
#define ASM_CONSOLE_LOGLEVEL DEFAULT_CONSOLE_LOGLEVEL
|
||||
#else
|
||||
|
|
16
src/include/part/fallback_boot.h
Normal file
16
src/include/part/fallback_boot.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef PART_FALLBACK_BOOT_H
|
||||
#define PART_FALLBACK_BOOT_H
|
||||
|
||||
#if !defined(ASSEMBLY)
|
||||
|
||||
#if USE_FALLBACK_BOOT
|
||||
void boot_successful(void);
|
||||
# else
|
||||
# define boot_successful()
|
||||
#endif
|
||||
|
||||
#endif /* ASSEMBLY */
|
||||
|
||||
#define RTC_BOOT_BYTE 48
|
||||
|
||||
#endif /* PART_FALLBACK_BOOT_H */
|
6
src/include/pc80/isa_dma.h
Normal file
6
src/include/pc80/isa_dma.h
Normal file
|
@ -0,0 +1,6 @@
|
|||
#ifndef PC80_ISA_DMA_H
|
||||
#define PC80_ISA_DMA_H
|
||||
|
||||
void isa_dma_init(void);
|
||||
|
||||
#endif /* PC80_ISA_DMA_H */
|
95
src/include/pc80/mc146818rtc.h
Normal file
95
src/include/pc80/mc146818rtc.h
Normal file
|
@ -0,0 +1,95 @@
|
|||
#ifndef PC80_MC146818RTC_H
|
||||
#define PC80_MC146818RTC_H
|
||||
|
||||
#ifndef RTC_BASE_PORT
|
||||
#define RTC_BASE_PORT 0x70
|
||||
#endif
|
||||
|
||||
#define RTC_PORT(x) (RTC_BASE_PORT + (x))
|
||||
|
||||
/* On PCs, the checksum is built only over bytes 16..45 */
|
||||
#define PC_CKS_RANGE_START 16
|
||||
#define PC_CKS_RANGE_END 45
|
||||
#define PC_CKS_LOC 46
|
||||
|
||||
|
||||
/* control registers - Moto names
|
||||
*/
|
||||
#define RTC_REG_A 10
|
||||
#define RTC_REG_B 11
|
||||
#define RTC_REG_C 12
|
||||
#define RTC_REG_D 13
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* register details
|
||||
**********************************************************************/
|
||||
#define RTC_FREQ_SELECT RTC_REG_A
|
||||
|
||||
/* update-in-progress - set to "1" 244 microsecs before RTC goes off the bus,
|
||||
* reset after update (may take 1.984ms @ 32768Hz RefClock) is complete,
|
||||
* totalling to a max high interval of 2.228 ms.
|
||||
*/
|
||||
# define RTC_UIP 0x80
|
||||
# define RTC_DIV_CTL 0x70
|
||||
/* divider control: refclock values 4.194 / 1.049 MHz / 32.768 kHz */
|
||||
# define RTC_REF_CLCK_4MHZ 0x00
|
||||
# define RTC_REF_CLCK_1MHZ 0x10
|
||||
# define RTC_REF_CLCK_32KHZ 0x20
|
||||
/* 2 values for divider stage reset, others for "testing purposes only" */
|
||||
# define RTC_DIV_RESET1 0x60
|
||||
# define RTC_DIV_RESET2 0x70
|
||||
/* Periodic intr. / Square wave rate select. 0=none, 1=32.8kHz,... 15=2Hz */
|
||||
# define RTC_RATE_SELECT 0x0F
|
||||
# define RTC_RATE_NONE 0x00
|
||||
# define RTC_RATE_32786HZ 0x01
|
||||
# define RTC_RATE_16384HZ 0x02
|
||||
# define RTC_RATE_8192HZ 0x03
|
||||
# define RTC_RATE_4096HZ 0x04
|
||||
# define RTC_RATE_2048HZ 0x05
|
||||
# define RTC_RATE_1024HZ 0x06
|
||||
# define RTC_RATE_512HZ 0x07
|
||||
# define RTC_RATE_256HZ 0x08
|
||||
# define RTC_RATE_128HZ 0x09
|
||||
# define RTC_RATE_64HZ 0x0a
|
||||
# define RTC_RATE_32HZ 0x0b
|
||||
# define RTC_RATE_16HZ 0x0c
|
||||
# define RTC_RATE_8HZ 0x0d
|
||||
# define RTC_RATE_4HZ 0x0e
|
||||
# define RTC_RATE_2HZ 0x0f
|
||||
|
||||
/**********************************************************************/
|
||||
#define RTC_CONTROL RTC_REG_B
|
||||
# define RTC_SET 0x80 /* disable updates for clock setting */
|
||||
# define RTC_PIE 0x40 /* periodic interrupt enable */
|
||||
# define RTC_AIE 0x20 /* alarm interrupt enable */
|
||||
# define RTC_UIE 0x10 /* update-finished interrupt enable */
|
||||
# define RTC_SQWE 0x08 /* enable square-wave output */
|
||||
# define RTC_DM_BINARY 0x04 /* all time/date values are BCD if clear */
|
||||
# define RTC_24H 0x02 /* 24 hour mode - else hours bit 7 means pm */
|
||||
# define RTC_DST_EN 0x01 /* auto switch DST - works f. USA only */
|
||||
|
||||
/**********************************************************************/
|
||||
#define RTC_INTR_FLAGS RTC_REG_C
|
||||
/* caution - cleared by read */
|
||||
# define RTC_IRQF 0x80 /* any of the following 3 is active */
|
||||
# define RTC_PF 0x40
|
||||
# define RTC_AF 0x20
|
||||
# define RTC_UF 0x10
|
||||
|
||||
/**********************************************************************/
|
||||
#define RTC_VALID RTC_REG_D
|
||||
# define RTC_VRT 0x80 /* valid RAM and time */
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
/* On PCs, the checksum is built only over bytes 16..45 */
|
||||
#define PC_CKS_RANGE_START 16
|
||||
#define PC_CKS_RANGE_END 45
|
||||
#define PC_CKS_LOC 46
|
||||
|
||||
#if !defined(ASSEMBLY)
|
||||
void rtc_init(int invalid);
|
||||
#endif
|
||||
|
||||
#endif /* PC80_MC146818RTC_H */
|
8
src/include/ramtest.h
Normal file
8
src/include/ramtest.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef RAMTEST_H
|
||||
#define RAMTEST_H
|
||||
|
||||
void ram_fill(unsigned long start, unsigned long stop);
|
||||
int ram_verify(unsigned long start, unsigned long stop, int max_errors);
|
||||
int ramcheck(unsigned long start, unsigned long stop, int max_errors);
|
||||
|
||||
#endif /* RAMTEST_H */
|
23
src/include/sdram.h
Normal file
23
src/include/sdram.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#ifndef SDRAM_H
|
||||
#define SDRAM_H
|
||||
|
||||
void sdram_no_memory(void);
|
||||
void sdram_initialize(void);
|
||||
void sdram_set_registers(void);
|
||||
void sdram_set_spd_registers(void);
|
||||
void sdram_enable(void);
|
||||
void sdram_first_normal_reference(void);
|
||||
void sdram_enable_refresh(void);
|
||||
void sdram_special_finishup(void);
|
||||
|
||||
void sdram_set_command_noop(void);
|
||||
void sdram_set_command_precharge(void);
|
||||
void sdram_set_command_cbr(void);
|
||||
void sdram_set_command_none(void);
|
||||
void sdram_assert_command(void);
|
||||
void sdram_set_mode_register(void);
|
||||
|
||||
void sdram_initialize_ecc(void);
|
||||
unsigned long sdram_get_ecc_size_bytes(void);
|
||||
|
||||
#endif /* SDRAM_H */
|
8
src/include/smbus.h
Normal file
8
src/include/smbus.h
Normal file
|
@ -0,0 +1,8 @@
|
|||
#ifndef SMBUS_H
|
||||
#define SMBUS_H
|
||||
|
||||
void smbus_enable(void);
|
||||
void smbus_setup(void);
|
||||
int smbus_read_byte(unsigned device, unsigned address, unsigned char *result);
|
||||
|
||||
#endif /* SMBUS_H */
|
|
@ -1,5 +1,13 @@
|
|||
#ifndef SOUTHBRIDGE_INTEL_82801_H
|
||||
#define SOUTHBRIDGE_INTEL_82801_H
|
||||
|
||||
void ich2_enable_serial_irqs(void);
|
||||
void ich2_lpc_route_dma(unsigned char mask);
|
||||
void ich2_enable_ioapic(void);
|
||||
void ich2_enable_ide(int enable_a, int enable_b);
|
||||
void ich2_hard_reset(void);
|
||||
void ich2_set_cpu_multiplier(unsigned);
|
||||
void ich2_rtc_init(void);
|
||||
void ich2_power_after_power_fail(int on);
|
||||
|
||||
#endif /* SOUTHBRIDGE_INTEL_82801_H */
|
||||
|
|
15
src/include/superio/generic.h
Normal file
15
src/include/superio/generic.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
#ifndef SUPERIO_GENERIC_H
|
||||
#define SUPERIO_GENERIC_H
|
||||
|
||||
void pnp_write_config(unsigned char port, unsigned char value, unsigned char reg);
|
||||
unsigned char pnp_read_config(unsigned char port, unsigned char reg);
|
||||
void pnp_set_logical_device(unsigned char port, int device);
|
||||
void pnp_set_enable(unsigned char port, int enable);
|
||||
int pnp_read_enable(unsigned char port);
|
||||
void pnp_set_iobase0(unsigned char port, unsigned iobase);
|
||||
void pnp_set_iobase1(unsigned char port, unsigned iobase);
|
||||
void pnp_set_irq0(unsigned char port, unsigned irq);
|
||||
void pnp_set_irq1(unsigned char port, unsigned irq);
|
||||
void pnp_set_drq(unsigned char port, unsigned drq);
|
||||
|
||||
#endif /* SUPERIO_GENERIC_H */
|
59
src/include/superio/w83627hf.h
Normal file
59
src/include/superio/w83627hf.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
#ifndef SUPERIO_W83627HF_H
|
||||
#define SUPERIO_W83627HF_H
|
||||
|
||||
/* The base address is 0x2e,0x4e depending on config bytes */
|
||||
#ifndef SIO_BASE
|
||||
#define SIO_BASE 0x2e
|
||||
#endif
|
||||
|
||||
#define SIO_SYSTEM_CLK_INPUT_48MHZ (1<<6)
|
||||
#define SIO_SYSTEM_CLK_INPUT_24MHZ (0<<6)
|
||||
|
||||
#if defined(SIO_SYSTEM_CLK_INPUT)
|
||||
#if (SIO_SYSTEM_CLK_INPUT != SIO_SYSTEM_CLK_INPUT_48MHZ) && (SIO_SYSTEM_CLK_INPUT != SIO_SYSTEM_CLK_INPUT_24MHZ)
|
||||
#error BAD SIO_SYSTEM_CLK_INPUT_PARAMETER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define FLOPPY_DEVICE 0
|
||||
#define PARALLEL_DEVICE 1
|
||||
#define COM1_DEVICE 2
|
||||
#define COM2_DEVICE 3
|
||||
#define KBC_DEVICE 5
|
||||
#define CIR_DEVICE 6
|
||||
#define GAME_PORT_DEVICE 7
|
||||
#define GPIO_PORT2_DEVICE 8
|
||||
#define GPIO_PORT3_DEVICE 9
|
||||
#define ACPI_DEVICE 0xa
|
||||
#define HW_MONITOR_DEVICE 0xb
|
||||
|
||||
|
||||
#define FLOPPY_DEFAULT_IOBASE 0x3f0
|
||||
#define FLOPPY_DEFAULT_IRQ 6
|
||||
#define FLOPPY_DEFAULT_DRQ 2
|
||||
#define PARALLEL_DEFAULT_IOBASE 0x378
|
||||
#define PARALLEL_DEFAULT_IRQ 7
|
||||
#define PARALLEL_DEFAULT_DRQ 4 /* No dma */
|
||||
#define COM1_DEFAULT_IOBASE 0x3f8
|
||||
#define COM1_DEFAULT_IRQ 4
|
||||
#define COM1_DEFAULT_BAUD 115200
|
||||
#define COM2_DEFAULT_IOBASE 0x2f8
|
||||
#define COM2_DEFAULT_IRQ 3
|
||||
#define COM2_DEFAULT_BAUD 115200
|
||||
#define KBC_DEFAULT_IOBASE0 0x60
|
||||
#define KBC_DEFAULT_IOBASE1 0x64
|
||||
#define KBC_DEFAULT_IRQ0 0x1
|
||||
#define KBC_DEFAULT_IRQ1 0xc
|
||||
|
||||
#if !defined(ASSEMBLY)
|
||||
void w83627hf_enter_pnp(unsigned char port);
|
||||
void w83627hf_exit_pnp(unsigned char port);
|
||||
|
||||
#define POWER_OFF 0
|
||||
#define POWER_ON 1
|
||||
#define POWER_PREV 2
|
||||
|
||||
void w832627hf_power_after_power_fail(int state);
|
||||
#endif
|
||||
|
||||
#endif /* SUPERIO_W83627HF_H */
|
|
@ -14,4 +14,4 @@ object malloc.o
|
|||
object elfboot.o
|
||||
object do_inflate.o
|
||||
object delay.o
|
||||
|
||||
object fallback_boot.o USE_FALLBACK_BOOT
|
||||
|
|
20
src/lib/fallback_boot.c
Normal file
20
src/lib/fallback_boot.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include <part/fallback_boot.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
#include <arch/io.h>
|
||||
#include <printk.h>
|
||||
|
||||
void boot_successful(void)
|
||||
{
|
||||
/* Remember I succesfully booted by setting
|
||||
* the initial boot direction
|
||||
* to the direction that I booted.
|
||||
*/
|
||||
unsigned char index, byte;
|
||||
index = inb(RTC_PORT(0)) & 0x80;
|
||||
index |= RTC_BOOT_BYTE;
|
||||
outb(index, RTC_PORT(0));
|
||||
|
||||
byte = inb(RTC_PORT(1));
|
||||
byte |= (byte & 2) >> 1;
|
||||
outb(byte, RTC_PORT(1));
|
||||
}
|
|
@ -139,12 +139,12 @@ void pci_get_size(struct pci_dev *dev, unsigned long reg, unsigned long addr)
|
|||
// This incidentally catches the common case where registers
|
||||
// read back as 0 for both address and size.
|
||||
if (addr == size) {
|
||||
printk_err(__FUNCTION__
|
||||
"dev_fn 0x%x, register %d, read-only"
|
||||
" SO, ignoring it\n",
|
||||
dev->devfn, reg);
|
||||
printk_err("addr was 0x%x, size was 0x%x\n",addr,size);
|
||||
type = 0;
|
||||
printk_debug(__FUNCTION__
|
||||
"dev_fn 0x%x, register %d, read-only"
|
||||
" SO, ignoring it\n",
|
||||
dev->devfn, reg);
|
||||
printk_debug("addr was 0x%x, size was 0x%x\n",addr,size);
|
||||
type = 0;
|
||||
size = 0;
|
||||
}
|
||||
// Now compute the actual size, See PCI Spec 6.2.5.1 ...
|
||||
|
|
|
@ -14,6 +14,7 @@ static char rcsid[] = "$Id$";
|
|||
#include <stdarg.h>
|
||||
#include <subr.h>
|
||||
#include <smp/spinlock.h>
|
||||
#include <printk.h>
|
||||
|
||||
/* printk's without a loglevel use this.. */
|
||||
#define DEFAULT_MESSAGE_LOGLEVEL 4 /* BIOS_WARNING */
|
||||
|
@ -21,10 +22,6 @@ static char rcsid[] = "$Id$";
|
|||
/* We show everything that is MORE important than this.. */
|
||||
#define MINIMUM_CONSOLE_LOGLEVEL 1 /* Minimum loglevel we let people use */
|
||||
|
||||
#ifndef DEFAULT_CONSOLE_LOGLEVEL
|
||||
#define DEFAULT_CONSOLE_LOGLEVEL 8 /* anything MORE serious than BIOS_SPEW */
|
||||
#endif
|
||||
|
||||
/* Keep together for sysctl support */
|
||||
|
||||
int console_loglevel = DEFAULT_CONSOLE_LOGLEVEL;
|
||||
|
|
|
@ -6,7 +6,9 @@ static char rcsid[] = "$Id$";
|
|||
#include <serial_subr.h>
|
||||
|
||||
/* Base Address */
|
||||
#define TTYS0 0x3f8
|
||||
#ifndef TTYS0_BASE
|
||||
#define TTYS0_BASE 0x3f8
|
||||
#endif
|
||||
|
||||
#ifndef TTYS0_BAUD
|
||||
#define TTYS0_BAUD 115200
|
||||
|
@ -153,29 +155,29 @@ inline void uart_init(unsigned base_port, unsigned divisor)
|
|||
|
||||
void ttys0_init(void)
|
||||
{
|
||||
uart_init(TTYS0, TTYS0_DIV);
|
||||
uart_init(TTYS0_BASE, TTYS0_DIV);
|
||||
}
|
||||
|
||||
void ttys0_tx_byte(unsigned char data)
|
||||
{
|
||||
uart_tx_byte(TTYS0, data);
|
||||
uart_tx_byte(TTYS0_BASE, data);
|
||||
}
|
||||
|
||||
unsigned char ttys0_rx_byte(void)
|
||||
{
|
||||
return uart_rx_byte(TTYS0);
|
||||
return uart_rx_byte(TTYS0_BASE);
|
||||
}
|
||||
|
||||
unsigned long ttys0_rx_bytes(char *buffer, unsigned long size)
|
||||
{
|
||||
return uart_rx_bytes(TTYS0, buffer, size);
|
||||
return uart_rx_bytes(TTYS0_BASE, buffer, size);
|
||||
}
|
||||
|
||||
#ifdef PYRO_SERIAL
|
||||
/* experimental serial read stuffs */
|
||||
int iskey(void)
|
||||
{
|
||||
return uart_have_rx_byte(TTYS0);
|
||||
return uart_have_rx_byte(TTYS0_BASE);
|
||||
}
|
||||
|
||||
char ttys0_rx_char(void)
|
||||
|
|
|
@ -324,7 +324,7 @@ int vtxprintf(void (*tx_byte)(unsigned char byte), const char *fmt, va_list args
|
|||
/* FIXME this global makes vsprintf non-reentrant
|
||||
*/
|
||||
static char *str_buf;
|
||||
static void str_tx_byte(char byte)
|
||||
static void str_tx_byte(unsigned char byte)
|
||||
{
|
||||
*str_buf = byte;
|
||||
str_buf++;
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
|
||||
mainboardinit northbridge/amd/amd76x/reset_test.inc
|
||||
mainboardinit cpu/k7/earlymtrr.inc
|
||||
mainboardinit northbridge/amd/amd76x/mpinit.inc
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <arch/io.h>
|
||||
#include <printk.h>
|
||||
#include <arch/pirq_routing.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
|
||||
#define CHECKSUM 0x8d
|
||||
|
||||
|
@ -168,6 +169,6 @@ void mainboard_fixup(void)
|
|||
southbridge_fixup();
|
||||
pci_functions_fixup();
|
||||
load_irq_routing_table();
|
||||
// rtc_init();
|
||||
// rtc_init(0);
|
||||
// pci_dump();
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
|
||||
mainboardinit northbridge/acer/m1631/chipset_init.inc
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
|
||||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
56
src/mainboard/intel/l440gx/mainboard_raminit.c
Normal file
56
src/mainboard/intel/l440gx/mainboard_raminit.c
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include <arch/cache_ram.h>
|
||||
#include <sdram.h>
|
||||
#include <smbus.h>
|
||||
#include <printk.h>
|
||||
#include <pci.h>
|
||||
#include <ramtest.h>
|
||||
|
||||
#define I440GX_BUS 0
|
||||
#define I440GX_DEVFN ((0 << 3) | 0)
|
||||
|
||||
static void debug_raminit(void)
|
||||
{
|
||||
int i;
|
||||
printk_debug("\n440GX registers");
|
||||
for(i = 0; i < 256; i++) {
|
||||
unsigned char byte;
|
||||
if ((i & 0x0f) == 0) {
|
||||
printk_debug("\n%02x: ", i);
|
||||
}
|
||||
pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, i, &byte);
|
||||
printk_debug("%02x ", byte);
|
||||
}
|
||||
printk_debug("\n");
|
||||
}
|
||||
|
||||
void cache_ram_start(void)
|
||||
{
|
||||
displayinit();
|
||||
printk_info("Hello from cache_ram_start\n");
|
||||
printk_debug("Calling pci_set_method\n");
|
||||
pci_set_method();
|
||||
printk_debug("Calling smbus_enable\n");
|
||||
smbus_enable();
|
||||
printk_debug("Calling smbus_setup\n");
|
||||
smbus_setup();
|
||||
printk_debug("Calling dump_spd_registers\n");
|
||||
dump_spd_registers();
|
||||
printk_debug("Calling sdram_initialize\n");
|
||||
sdram_initialize();
|
||||
printk_debug("Calling debug_raminit\n");
|
||||
debug_raminit();
|
||||
printk_debug("Calling sdram_initialize_ecc\n");
|
||||
sdram_initialize_ecc();
|
||||
printk_debug("Calling ramcheck\n");
|
||||
#if 0
|
||||
ramcheck(0, 128*1024, 30);
|
||||
ramcheck(128*1024, (128+64)*1024, 30);
|
||||
ramcheck(256*1024, (256+64)*1024, 30);
|
||||
ramcheck((256+128)*1024, 512*1024, 30);
|
||||
ramcheck(512*1024, 640*1024, 30);
|
||||
ramcheck(1024*1024, (1024*1024) + (128*1024), 30);
|
||||
ramcheck(64*1024*1024, (64*1024*1024) + (128*1024), 30);
|
||||
ramcheck(127*1024*1024, 128*1024*1024, 30);
|
||||
#endif
|
||||
printk_debug("ram is setup\n");
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
|
||||
mainboardinit superio/sis/950/setup_serial.inc
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
|
||||
mainboardinit superio/sis/950/setup_serial.inc
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
|
||||
# These are ONLY used for doc.
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
|
||||
mainboardinit superio/sis/950/setup_serial.inc
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
|
||||
mainboardinit superio/via/vt82c686/setup_serial.inc
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
|
||||
mainboardinit superio/sis/950/setup_serial.inc
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
|
||||
northsouthbridge sis/550
|
||||
|
|
|
@ -1,31 +1,43 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
mainboardinit cpu/i386/reset16.inc USE_FALLBACK_IMAGE
|
||||
ldscript cpu/i386/reset16.lds USE_FALLBACK_IMAGE
|
||||
mainboardinit cpu/i386/reset32.inc USE_NORMAL_IMAGE
|
||||
ldscript cpu/i386/reset32.lds USE_NORMAL_IMAGE
|
||||
|
||||
#rambase 0x04000000
|
||||
biosbase 0xffff0000
|
||||
option XIP_ROM_BASE=0xffff0000
|
||||
option XIP_ROM_SIZE=0x10000
|
||||
option ROM_IMAGE_SIZE=32768
|
||||
rambase 0x00008000
|
||||
option USE_CACHE_RAM=1
|
||||
option CACHE_RAM_BASE=0xfff70000
|
||||
option CACHE_RAM_SIZE=0x00010000
|
||||
option USE_CACHE_RAM=1
|
||||
nooption USE_DEFAULT_LAYOUT
|
||||
#rambase 0xfff70000
|
||||
rambase 0x00000800
|
||||
option STACK_SIZE=0x2000
|
||||
option USE_FALLBACK_BOOT=1
|
||||
|
||||
#/* falback */
|
||||
option ZKERNEL_START=0xffff0000
|
||||
option _ROMBASE= 0xffff8000
|
||||
option XIP_ROM_BASE= 0xffff8000
|
||||
option XIP_ROM_SIZE= 0x00008000
|
||||
##/* normal image */
|
||||
#option ZKERNEL_START=0xfff80000
|
||||
#option _ROMBASE= 0xfffe8000
|
||||
#option XIP_ROM_BASE= 0xfffe8000
|
||||
#option XIP_ROM_SIZE= 0x00008000
|
||||
|
||||
mainboardinit northbridge/intel/82860/reset_test.inc
|
||||
mainboardinit arch/i386/lib/noop_failover.inc USE_NORMAL_IMAGE
|
||||
mainboardinit southbridge/intel/82801/cmos_failover.inc USE_FALLBACK_IMAGE
|
||||
ldscript arch/i386/lib/failover.lds USE_FALLBACK_IMAGE
|
||||
|
||||
#mainboardinit southbridge/intel/82801/definitions.inc
|
||||
#mainboardinit southbridge/intel/82801/disable_watchdog.inc
|
||||
#mainboardinit southbridge/intel/82801/lpc_com1.inc
|
||||
mainboardinit cpu/i786/earlymtrr.inc
|
||||
|
||||
mainboardinit superio/winbond/w83627hf/setup_serial.inc
|
||||
mainboardinit pc80/serial.inc
|
||||
mainboardinit arch/i386/lib/console.inc
|
||||
|
||||
#mainboardinit ram/ramtest.inc
|
||||
#mainboardinit northbridge/intel/82860/reset_test.inc
|
||||
mainboardinit cpu/i786/cache_ram_init.inc
|
||||
|
@ -52,6 +64,7 @@ object mptable.o HAVE_MP_TABLE
|
|||
object irq_tables.o HAVE_PIRQ_TABLE
|
||||
#keyboard pc80
|
||||
dir ../../../pc80
|
||||
dir /src/superio/winbond/w83627hf
|
||||
|
||||
# FIXME are the SMBUS DIMM locations documented anywhere?
|
||||
option SMBUS_MEM_DEVICE_START=(0xa << 3)
|
||||
|
|
10
src/mainboard/supermicro/p4dc6/failover.inc
Normal file
10
src/mainboard/supermicro/p4dc6/failover.inc
Normal file
|
@ -0,0 +1,10 @@
|
|||
#define MCH_RICM 0x94
|
||||
#define RICM_DONE (1 << 27)
|
||||
/* If I have already booted once skip a bunch of initialization */
|
||||
/* To see if I have already booted I check to see if memory
|
||||
* has been enabled.
|
||||
*/
|
||||
movl $MCH_RICM, %eax
|
||||
PCI_READ_CONFIG_DWORD
|
||||
testl $RICM_DONE, %eax
|
||||
jnz __cpu_reset
|
|
@ -5,29 +5,36 @@
|
|||
#include <pci_ids.h>
|
||||
#include <southbridge/intel/82801.h>
|
||||
#include <arch/smp/mpspec.h>
|
||||
#include <pc80/isa_dma.h>
|
||||
#include <cpu/i786/multiplier.h>
|
||||
#include <superio/w83627hf.h>
|
||||
|
||||
unsigned long initial_apicid[MAX_CPUS] =
|
||||
{
|
||||
0, 6
|
||||
};
|
||||
|
||||
|
||||
void mainboard_fixup(void)
|
||||
{
|
||||
ich2_enable_ioapic();
|
||||
ich2_enable_serial_irqs();
|
||||
ich2_enable_ide(1,1);
|
||||
rtc_init();
|
||||
ich2_rtc_init();
|
||||
ich2_lpc_route_dma(0xff);
|
||||
isa_dma_init();
|
||||
#if 1
|
||||
/* FIXME don't hard code these */
|
||||
ich2_set_cpu_multiplier(XEON_X17);
|
||||
#endif
|
||||
ich2_power_after_power_fail(1);
|
||||
w832627hf_power_after_power_fail(POWER_ON);
|
||||
printk_notice("Please add a mainboard_fixup!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
void hard_reset(void)
|
||||
{
|
||||
/* Try rebooting through port 0xcf9 */
|
||||
outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
|
||||
return;
|
||||
ich2_hard_reset();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <part/mainboard.h>
|
||||
#include <part/hard_reset.h>
|
||||
#include <arch/smp/mpspec.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
|
||||
unsigned long initial_apicid[MAX_CPUS] =
|
||||
{
|
||||
|
@ -515,7 +516,7 @@ void mainboard_fixup(void)
|
|||
setup_ide_devices();
|
||||
onboard_scsi_fixup();
|
||||
cpu_reset_sends_init();
|
||||
rtc_init();
|
||||
rtc_init(0);
|
||||
decode_stop_grant_fixup();
|
||||
posted_memory_write_enable();
|
||||
pm_controller_classcode_fixup();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
mainboardinit cpu/i386/reset16.inc
|
||||
ldscript cpu/i386/reset16.lds
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
arch i386
|
||||
mainboardinit cpu/i386/entry16.inc
|
||||
mainboardinit cpu/i386/entry32.inc
|
||||
ldscript cpu/i386/entry16.lds
|
||||
|
||||
mainboardinit superio/via/vt82c686/setup_serial.inc
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
mainboardinit arch/i386/lib/set_memory_size_noop.inc
|
||||
mainboardinit northbridge/intel/440gx/raminit.inc
|
||||
mainboardinit sdram/generic_sdram_enable.inc
|
||||
mainboardinit sdram/generic_sdram.inc
|
||||
mainboardinit sdram/generic_zero_ecc_sdram.inc
|
||||
mainboardinit northbridge/intel/440gx/raminit.inc USE_DEFAULT_LAYOUT
|
||||
mainboardinit sdram/generic_sdram_enable.inc USE_DEFAULT_LAYOUT
|
||||
mainboardinit sdram/generic_sdram.inc USE_DEFAULT_LAYOUT
|
||||
mainboardinit sdram/generic_zero_ecc_sdram.inc USE_DEFAULT_LAYOUT
|
||||
mainboardinit arch/i386/lib/cpu_reset.inc
|
||||
|
||||
object northbridge.o
|
||||
|
||||
object raminit.o USE_CACHE_RAM
|
||||
|
|
796
src/northbridge/intel/440gx/raminit.c
Normal file
796
src/northbridge/intel/440gx/raminit.c
Normal file
|
@ -0,0 +1,796 @@
|
|||
#include <sdram.h>
|
||||
#include <printk.h>
|
||||
#include <arch/cache_ram.h>
|
||||
#include <pci.h>
|
||||
#include <smbus.h>
|
||||
#include <bitops.h>
|
||||
|
||||
#define I440GX_BUS 0
|
||||
#define I440GX_DEVFN ((0x00 << 3) + 0)
|
||||
|
||||
#define USE_ECC 0
|
||||
|
||||
#define CAS_LATENCY 3
|
||||
|
||||
/* CAS latency 2 */
|
||||
#if (CAS_LATENCY == 2)
|
||||
#define CAS_NB 0x17
|
||||
/*
|
||||
* 7 == 0111
|
||||
* 1 == 0001
|
||||
*/
|
||||
#define CAS_MODE 0x2a
|
||||
/*
|
||||
* a == 1010
|
||||
* 2 == 0010
|
||||
*/
|
||||
#endif
|
||||
|
||||
/* CAS latency 3 */
|
||||
#if (CAS_LATENCY == 3)
|
||||
#define CAS_NB 0x13
|
||||
/*
|
||||
* 3 == 0011
|
||||
* 1 == 0001
|
||||
*/
|
||||
#define CAS_MODE 0x3a
|
||||
/*
|
||||
* a == 1010
|
||||
* 3 == 0011
|
||||
*/
|
||||
#endif
|
||||
|
||||
#ifndef CAS_NB
|
||||
#error "Nothing defined"
|
||||
#endif
|
||||
|
||||
|
||||
/* Default values for config registers */
|
||||
|
||||
static void set_nbxcfg(void)
|
||||
{
|
||||
/* NBXCFG 0x50 - 0x53 */
|
||||
/* f == 1111
|
||||
* 0 == 0000
|
||||
* 0 == 0000
|
||||
* 0 == 0000
|
||||
* 0 == 0000
|
||||
* 1 == 0001
|
||||
* 8 == 1000
|
||||
* c == 1100
|
||||
* SDRAM Row without ECC:
|
||||
* row 0 == 1 No ECC
|
||||
* row 1 == 1 No ECC
|
||||
* row 2 == 1 No ECC
|
||||
* row 3 == 1 No ECC
|
||||
* row 4 == 1 No ECC
|
||||
* row 5 == 1 No ECC
|
||||
* row 6 == 1 No ECC
|
||||
* row 7 == 1 No ECC
|
||||
* Host Bus Fast Data Ready Enable == 0 Disabled
|
||||
* IDSEL_REDIRECT == 0 (430TX compatibility disable?)
|
||||
* WSC# Hanshake Disable == 0 enable (Use External IOAPIC)
|
||||
* Host/DRAM Frequence == 00 100Mhz
|
||||
* AGP to PCI Access Enable == 0 Disable
|
||||
* PCI Agent to Aperture Access Disable == 0 Enable (Ignored)
|
||||
* Aperture Access Global Enable == 0 Disable
|
||||
* DRAM Data Integrity Mode == 11 (Error Checking/Correction)
|
||||
* ECC Diagnostic Mode Enable == 0 Not Enabled
|
||||
* MDA present == 0 Not Present
|
||||
* USWC Write Post During During I/O Bridge Access Enable == 1 Enabled
|
||||
* In Order Queue Depth (IQD) (RO) == ??
|
||||
*/
|
||||
pcibios_write_config_dword(I440GX_BUS, I440GX_DEVFN, 0x50, 0xff00000c);
|
||||
}
|
||||
|
||||
static void set_dramc(void)
|
||||
{
|
||||
/* 0 == 0000
|
||||
* 8 == 1000
|
||||
* Not registered SDRAM
|
||||
* refresh disabled
|
||||
*/
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57, 0x8);
|
||||
}
|
||||
|
||||
static void set_pam(void)
|
||||
{
|
||||
/* 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...
|
||||
*/
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x59, 0x00);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x5a, 0x00);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x5b, 0x00);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x5d, 0x00);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x5e, 0x00);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x5f, 0x00);
|
||||
}
|
||||
|
||||
static void set_drb(void)
|
||||
{
|
||||
/* DRB - DRAM Row Boundary Registers */
|
||||
/* Conservative setting 8MB of ram on first DIMM... */
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x60, 0x01);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x61, 0x01);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x62, 0x01);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x63, 0x01);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x64, 0x01);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x65, 0x01);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x66, 0x01);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x67, 0x01);
|
||||
}
|
||||
|
||||
static void set_fdhc(void)
|
||||
{
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x68, 0x00);
|
||||
}
|
||||
static void set_mbsc(void)
|
||||
{
|
||||
/* MBSC - Memory Buffer Strength Control */
|
||||
/* 00c00003e820
|
||||
* [47:44] 0 == 0000
|
||||
* [43:40] 0 == 0000
|
||||
* [39:36] c == 1100
|
||||
* [35:32] 0 == 0000
|
||||
* [31:28] 0 == 0000
|
||||
* [27:24] 0 == 0000
|
||||
* [23:20] 0 == 0000
|
||||
* [19:16] 3 == 0011
|
||||
* [15:12] e == 1110
|
||||
* [11: 8] 8 == 1000
|
||||
* [ 7: 4] 2 == 0010
|
||||
* [ 3: 0] 0 == 0000
|
||||
* MAA[14:0]#, WEA#, SRASA#, SCASA# Buffer Strengths == 3x
|
||||
* MAB[14,13,10,12:11,9:0]#, WEB#, SRASB#, SCASB# Buffer Strengths == 3x
|
||||
* MD[63:0]# Buffer Strength Control 2 == 3x
|
||||
* MD[63:0]# Buffer Strength Control 1 == 3x
|
||||
* MECC[7:0] Buffer Strength Control 2 == 3x
|
||||
* MECC[7:0] Buffer Strength Control 1 == 3x
|
||||
* CSB7# Buffer Strength == 3x
|
||||
* CSA7# Buffer Strength == 3x
|
||||
* CSB6# Buffer Strength == 3x
|
||||
* CSA6# Buffer Strength == 3x
|
||||
* CSA5#/CSB5# Buffer Strength == 2x
|
||||
* CSA4#/CSB4# Buffer Strength == 2x
|
||||
* CSA3#/CSB3# Buffer Strength == 2x
|
||||
* CSA2#/CSB2# Buffer Strength == 2x
|
||||
* CSA1#/CSB1# Buffer Strength == 2x
|
||||
* CSA0#/CSB0# Buffer Strength == 2x
|
||||
* DQMA5 Buffer Strength == 2x
|
||||
* DQMA1 Buffer Strength == 3x
|
||||
* DQMB5 Buffer Strength == 2x
|
||||
* DQMB1 Buffer Strength == 2x
|
||||
* DQMA[7:6,4:2,0] Buffer Strength == 3x
|
||||
* GCKE Buffer Strength == 1x
|
||||
* FENA Buffer Strength == 3x
|
||||
*/
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x69, 0xB3);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x6a, 0xee);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x6b, 0xff);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x6c, 0xff);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x6d, 0xff);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x6e, 0x03);
|
||||
}
|
||||
|
||||
static void set_smram(void)
|
||||
{
|
||||
/* 0x72 SMRAM */
|
||||
/* 1 == 0001
|
||||
* a == 1010
|
||||
* SMM Compatible base segment == 010 (Hardcoded value)
|
||||
*/
|
||||
}
|
||||
|
||||
static void set_esramc(void)
|
||||
{
|
||||
/* 0x73 ESMRAMC */
|
||||
}
|
||||
|
||||
static void set_rps(void)
|
||||
{
|
||||
/* RPS - Row Page Size Register */
|
||||
/* 0x0055
|
||||
* [15:12] 0 == 0000
|
||||
* [11: 8] 0 == 0000
|
||||
* [ 7: 4] 5 == 0101
|
||||
* [ 3: 0] 5 == 0101
|
||||
* DRB[0] == 4KB
|
||||
* DRB[1] == 4KB
|
||||
* DRB[2] == 4KB
|
||||
* DRB[3] == 4KB
|
||||
* DRB[4] == 2KB
|
||||
* DRB[5] == 2KB
|
||||
* DRB[6] == 2KB
|
||||
* DRB[7] == 2KB
|
||||
*/
|
||||
pcibios_write_config_word(I440GX_BUS, I440GX_DEVFN, 0x74, 0x5555);
|
||||
}
|
||||
|
||||
static void set_sdramc(void)
|
||||
{
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76, CAS_NB);
|
||||
}
|
||||
|
||||
static void set_pgpol(void)
|
||||
{
|
||||
/* PGPOL - Paging Policy Register */
|
||||
/* 0xff07
|
||||
* [15:12] f == 1111
|
||||
* [11: 8] f == 1111
|
||||
* [ 7: 4] 0 == 0000
|
||||
* [ 3: 0] 7 == 0111
|
||||
* row0 == 4banks
|
||||
* row1 == 4banks
|
||||
* row2 == 4banks
|
||||
* row3 == 4banks
|
||||
* row4 == 4banks
|
||||
* row5 == 4banks
|
||||
* row6 == 4banks
|
||||
* row7 == 4banks
|
||||
* Dram Idle Timer (DIT) == 32 clocks
|
||||
*/
|
||||
pcibios_write_config_word(I440GX_BUS, I440GX_DEVFN, 0x78, 0xff07);
|
||||
}
|
||||
|
||||
static void set_mbfs(void)
|
||||
{
|
||||
/* MBFS - Memory Buffer Frequencey Select Register */
|
||||
/* 0xffff7f
|
||||
* [23:20] f == 1111
|
||||
* [19:16] f == 1111
|
||||
* [15:12] f == 1111
|
||||
* [11: 8] f == 1111
|
||||
* [ 7: 4] 7 == 0111
|
||||
* [ 3: 0] f == 1111
|
||||
* MAA[14:0], WEA#, SRASA#, SCASA# == 100Mhz Buffers Enabled
|
||||
* MAB[14,13,10,12:11,9:0], WEB#, SRASB#, SCASB# == 100Mhz Buffers Enabled
|
||||
* MD[63:0] Control 2 == 100 Mhz Buffer Enable
|
||||
* MD[63:0] Control 1 == 100 Mhz B
|
||||
* MECC[7:0] Control 2 == 100 Mhz B
|
||||
*
|
||||
*/
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xca, 0xff);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xcb, 0xff);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xcc, 0x7f);
|
||||
}
|
||||
|
||||
static void set_dwtc(void)
|
||||
{
|
||||
/* DWTC - DRAM Write Thermal Throttle Control */
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe0, 0xb4);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe1, 0xbe);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe2, 0xff);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe3, 0xd7);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe4, 0x97);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe5, 0x3e);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe6, 0x00);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe7, 0x80);
|
||||
}
|
||||
|
||||
static void set_drtc(void)
|
||||
{
|
||||
/* DRTC - DRAM Read Thermal Throttle Control */
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe8, 0x2c);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xe9, 0xd3);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xea, 0xf7);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xeb, 0xcf);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xec, 0x9d);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xed, 0x3e);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xee, 0x00);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xef, 0x00);
|
||||
}
|
||||
|
||||
static void set_pmcr(void)
|
||||
{
|
||||
/* PMCR -- BIOS sets 0x90 into it.
|
||||
* 0x10 is REQUIRED.
|
||||
* we have never used it. So why did this ever work?
|
||||
*/
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x7a, 0x90);
|
||||
|
||||
}
|
||||
void sdram_set_registers(void)
|
||||
{
|
||||
set_nbxcfg();
|
||||
set_dramc();
|
||||
set_pam();
|
||||
set_drb();
|
||||
set_fdhc();
|
||||
set_mbsc();
|
||||
set_smram();
|
||||
set_esramc();
|
||||
set_rps();
|
||||
set_sdramc();
|
||||
set_pgpol();
|
||||
set_mbfs();
|
||||
set_dwtc();
|
||||
set_drtc();
|
||||
set_pmcr();
|
||||
}
|
||||
|
||||
|
||||
static void spd_set_drb(void)
|
||||
{
|
||||
/*
|
||||
* Effects: Uses serial presence detect to set the
|
||||
* DRB registers which holds the ending memory address assigned
|
||||
* to each DIMM.
|
||||
*/
|
||||
unsigned end_of_memory;
|
||||
unsigned device;
|
||||
unsigned drb_reg;
|
||||
|
||||
end_of_memory = 0; /* in multiples of 8MiB */
|
||||
device = SMBUS_MEM_DEVICE_START;
|
||||
drb_reg = 0x60;
|
||||
while (device <= SMBUS_MEM_DEVICE_END) {
|
||||
unsigned side1_bits, side2_bits;
|
||||
unsigned char byte, byte2;
|
||||
int status;
|
||||
|
||||
side1_bits = side2_bits = -1;
|
||||
|
||||
/* rows */
|
||||
status = smbus_read_byte(device, 3, &byte);
|
||||
if (status != 0) goto set_drb_reg;
|
||||
side1_bits += byte & 0xf;
|
||||
|
||||
/* columns */
|
||||
status = smbus_read_byte(device, 4, &byte);
|
||||
side1_bits += byte & 0xf;
|
||||
|
||||
/* banks */
|
||||
status = smbus_read_byte(device, 17, &byte);
|
||||
side1_bits += log2(byte);
|
||||
|
||||
/* Get the moduel data width and convert it to a power of two */
|
||||
/* low byte */
|
||||
status = smbus_read_byte(device, 6, &byte);
|
||||
/* high byte */
|
||||
status = smbus_read_byte(device, 7, &byte2);
|
||||
side1_bits += log2((((unsigned long)byte2 << 8)| byte));
|
||||
|
||||
/* now I have the ram size in bits as a power of two (less 1) */
|
||||
/* Make it mulitples of 8MB */
|
||||
side1_bits -= 25;
|
||||
|
||||
/* side two */
|
||||
|
||||
/* number of physical banks */
|
||||
status = smbus_read_byte(device, 5, &byte);
|
||||
if (byte <= 1) goto set_drb_reg;
|
||||
|
||||
/* for now only handle the symmetrical case */
|
||||
side2_bits = side1_bits;
|
||||
|
||||
set_drb_reg:
|
||||
/* Compute the end address for the DRB register */
|
||||
/* Only process dimms < 2GB (2^8 * 8MB) */
|
||||
if (side1_bits < 8) {
|
||||
end_of_memory += (1 << side1_bits);
|
||||
}
|
||||
printk_debug("end_of_memory: %08x\n", end_of_memory);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, drb_reg, end_of_memory);
|
||||
|
||||
if (side2_bits < 8 ) {
|
||||
end_of_memory += (1 << side2_bits);
|
||||
}
|
||||
printk_debug("end_of_memory: %08x\n", end_of_memory);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, drb_reg +1, end_of_memory);
|
||||
|
||||
drb_reg += 2;
|
||||
device += SMBUS_MEM_DEVICE_INC;
|
||||
}
|
||||
}
|
||||
|
||||
static void spd_set_dramc(void)
|
||||
{
|
||||
/*
|
||||
* Effects: Uses serial presence detect to set the
|
||||
* DRAMC register, which records if ram is registerd or not,
|
||||
* and controls the refresh rate.
|
||||
* The refresh rate is not set here, as memory refresh
|
||||
* cannot be enbaled until after memory is initialized.
|
||||
* see spd_enable_refresh.
|
||||
*/
|
||||
/* 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 */
|
||||
/* FIXME Check for illegal/unsupported ram configurations and abort */
|
||||
unsigned device;
|
||||
int status;
|
||||
unsigned char byte;
|
||||
unsigned dramc;
|
||||
status = -1;
|
||||
device = SMBUS_MEM_DEVICE_START;
|
||||
while ((status != 0) && (device <= SMBUS_MEM_DEVICE_END)) {
|
||||
status = smbus_read_byte(device, 21, &byte);
|
||||
device += SMBUS_MEM_DEVICE_INC;
|
||||
}
|
||||
if (status != 0) {
|
||||
/* We couldn't find anything we must have no memory */
|
||||
sdram_no_memory();
|
||||
}
|
||||
dramc = 0x8;
|
||||
if ((byte & 0x12) != 0) {
|
||||
/* this is a registered part.
|
||||
* observation: for register parts, BIOS zeros (!)
|
||||
* registers CA-CC. This has an undocumented meaning.
|
||||
*/
|
||||
/* But it does make sense the oppisite of registered
|
||||
* sdram is buffered and 0xca - 0xcc control the buffers.
|
||||
* Clearing them aparently disables them.
|
||||
*/
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xca, 0);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xcb, 0);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0xcc, 0);
|
||||
dramc = 0x10;
|
||||
}
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57, dramc);
|
||||
}
|
||||
|
||||
static void spd_enable_refresh(void)
|
||||
{
|
||||
/*
|
||||
* Effects: Uses serial presence detect to set the
|
||||
* refresh rate in the DRAMC register.
|
||||
* see spd_set_dramc for the other values.
|
||||
* FIXME: Check for illegal/unsupported ram configurations and abort
|
||||
*/
|
||||
static const unsigned char refresh_rates[] = {
|
||||
0x01, /* Normal 15.625 us -> 15.6 us */
|
||||
0x05, /* Reduced(.25X) 3.9 us -> 7.8 us */
|
||||
0x05, /* Reduced(.5X) 7.8 us -> 7.8 us */
|
||||
0x02, /* Extended(2x) 31.3 us -> 31.2 us */
|
||||
0x03, /* Extended(4x) 62.5 us -> 62.4 us */
|
||||
0x04, /* Extended(8x) 125 us -> 124.8 us */
|
||||
};
|
||||
/* Find the first dimm and assume the rest are the same */
|
||||
int status;
|
||||
unsigned char byte;
|
||||
unsigned device;
|
||||
unsigned refresh_rate;
|
||||
byte = 0;
|
||||
status = -1;
|
||||
device = SMBUS_MEM_DEVICE_START;
|
||||
while ((status != 0) && (device <= SMBUS_MEM_DEVICE_END)) {
|
||||
status = smbus_read_byte(device, 12, &byte);
|
||||
device += SMBUS_MEM_DEVICE_INC;
|
||||
}
|
||||
if (status != 0) {
|
||||
/* We couldn't find anything we must have no memory */
|
||||
sdram_no_memory();
|
||||
}
|
||||
byte &= 0x7f;
|
||||
/* Default refresh rate be conservative */
|
||||
refresh_rate = 5;
|
||||
/* see if the ram refresh is a supported one */
|
||||
if (byte < 6) {
|
||||
refresh_rate = refresh_rates[byte];
|
||||
}
|
||||
pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57, &byte);
|
||||
byte &= 0xf8;
|
||||
byte |= refresh_rate;
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57, byte);
|
||||
}
|
||||
|
||||
static void spd_set_sdramc(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void spd_set_rps(void)
|
||||
{
|
||||
/*
|
||||
* Effects: Uses serial presence detect to set the row size
|
||||
* on a given DIMM
|
||||
* FIXME: Check for illegal/unsupported ram configurations and abort
|
||||
*/
|
||||
/* The RPS register holds the size of a ``page'' of DRAM on each DIMM */
|
||||
unsigned page_sizes;
|
||||
unsigned index;
|
||||
unsigned device;
|
||||
unsigned char dramc;
|
||||
/* default all page sizes to 2KB */
|
||||
page_sizes = 0;
|
||||
index = 0;
|
||||
device = SMBUS_MEM_DEVICE_START;
|
||||
while (device <= SMBUS_MEM_DEVICE_END) {
|
||||
int status;
|
||||
unsigned char byte;
|
||||
int page_size;
|
||||
|
||||
status = smbus_read_byte(device, 3, &byte);
|
||||
if (status != 0) goto next;
|
||||
|
||||
/* I now have the row page size as a power of 2 */
|
||||
page_size = byte & 0xf;
|
||||
/* make it in multiples of 2Kb */
|
||||
page_size -= 11;
|
||||
if (page_size <= 0) goto next;
|
||||
/* FIXME: do something with page sizes greather than 8KB!! */
|
||||
page_sizes |= (page_size << index);
|
||||
|
||||
/* side two */
|
||||
status = smbus_read_byte(device, 5, &byte);
|
||||
if (byte <= 1) goto next;
|
||||
|
||||
/* For now only handle the symmetrical case */
|
||||
page_sizes |= (page_size << (index +2));
|
||||
|
||||
next:
|
||||
index += 4;
|
||||
device += SMBUS_MEM_DEVICE_INC;
|
||||
}
|
||||
|
||||
/* 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, page_sizes 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.
|
||||
*/
|
||||
|
||||
pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x57, &dramc);
|
||||
if (dramc & 0x10) {
|
||||
/* registered */
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
page_sizes += 0x1111;
|
||||
}
|
||||
|
||||
pcibios_write_config_word(I440GX_BUS, I440GX_DEVFN, 0x74, page_sizes);
|
||||
}
|
||||
|
||||
static void spd_set_pgpol(void)
|
||||
{
|
||||
/*
|
||||
* Effects: Uses serial presence detect to set the number of banks
|
||||
* on a given DIMM
|
||||
* FIXME: Check for illegal/unsupported ram configurations and abort
|
||||
*/
|
||||
/* The PGPOL register stores the number of logical banks per DIMM,
|
||||
* and number of clocks the DRAM controller waits in the idle
|
||||
* state.
|
||||
*/
|
||||
unsigned device;
|
||||
unsigned bank_sizes;
|
||||
unsigned bank;
|
||||
unsigned reg;
|
||||
/* default all bank counts 2 */
|
||||
bank_sizes = 0;
|
||||
bank = 0;
|
||||
device = SMBUS_MEM_DEVICE_START;
|
||||
while (device <= SMBUS_MEM_DEVICE_END) {
|
||||
int status;
|
||||
unsigned char byte;
|
||||
|
||||
/* logical banks */
|
||||
status = smbus_read_byte(device, 17, &byte);
|
||||
if (status != 0) goto next;
|
||||
if (byte < 4) goto next;
|
||||
bank_sizes |= (1 << bank);
|
||||
|
||||
/* side 2 */
|
||||
/* Number of physical banks */
|
||||
status = smbus_read_byte(device, 5, &byte);
|
||||
if (byte <= 1) goto next;
|
||||
/* for now only handle the symmetrical case */
|
||||
bank_sizes |= (1 << (bank +1));
|
||||
next:
|
||||
bank += 2;
|
||||
device += SMBUS_MEM_DEVICE_INC;
|
||||
}
|
||||
reg = bank_sizes << 8;
|
||||
reg |= 0x7; /* 32 clocks idle time */
|
||||
pcibios_write_config_word(I440GX_BUS, I440GX_DEVFN, 0x78, reg);
|
||||
}
|
||||
|
||||
static void spd_set_nbxcfg(void)
|
||||
{
|
||||
/*
|
||||
* Effects: Uses serial presence detect to set the
|
||||
* ECC support flags in the NBXCFG register
|
||||
* FIXME: Check for illegal/unsupported ram configurations and abort
|
||||
*/
|
||||
unsigned reg;
|
||||
unsigned index;
|
||||
unsigned device;
|
||||
|
||||
/* Say all dimms have no ECC support */
|
||||
reg = 0xff;
|
||||
index = 0;
|
||||
|
||||
device = SMBUS_MEM_DEVICE_START;
|
||||
while (device <= SMBUS_MEM_DEVICE_END) {
|
||||
int status;
|
||||
unsigned char byte;
|
||||
|
||||
status = smbus_read_byte(device, 11, &byte);
|
||||
if (status != 0) goto next;
|
||||
#if !USE_ECC /* Disable ECC */
|
||||
byte = 0;
|
||||
#endif
|
||||
/* 0 == None, 1 == Parity, 2 == ECC */
|
||||
if (byte != 2) goto next;
|
||||
reg ^= (1 << index);
|
||||
|
||||
/* side two */
|
||||
/* number of physical banks */
|
||||
status = smbus_read_byte(device, 5, &byte);
|
||||
if (byte <= 1) goto next;
|
||||
/* There is only the symmetrical case */
|
||||
reg ^= (1 << (index +1));
|
||||
next:
|
||||
index += 2;
|
||||
device += SMBUS_MEM_DEVICE_INC;
|
||||
}
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x53, reg);
|
||||
/* Now see if reg is 0xff. If it is we are done. If not,
|
||||
* we need to set 0x18 into regster 0x50.l
|
||||
* we will do this in two steps, first or in 0x80 to 0x50.b,
|
||||
* then or in 0x1 to 0x51.b
|
||||
*/
|
||||
printk_debug("spd_set_nbxcfg reg=0x%02x\n", reg);
|
||||
if (reg != 0xff) {
|
||||
unsigned char byte;
|
||||
pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x50, &byte);
|
||||
byte |= 0x80;
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x50, byte);
|
||||
pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x51, &byte);
|
||||
byte |= 1;
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x51, byte);
|
||||
/* try this.
|
||||
* We should be setting bit 2 in register 76 and we're not
|
||||
* technically we should see if CL=2 for the ram,
|
||||
* but registered is so screwed up that it's kind of a lost
|
||||
* cause.
|
||||
*/
|
||||
pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76, &byte);
|
||||
byte |= 4;
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76, byte);
|
||||
printk_debug("spd_set_nbxcfg 0x76.b=0x%02x\n", byte);
|
||||
}
|
||||
}
|
||||
|
||||
void sdram_set_spd_registers(void)
|
||||
{
|
||||
spd_set_drb();
|
||||
spd_set_dramc();
|
||||
spd_set_rps();
|
||||
spd_set_sdramc();
|
||||
spd_set_pgpol();
|
||||
spd_set_nbxcfg();
|
||||
}
|
||||
|
||||
void sdram_first_normal_reference(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
void sdram_special_finishup(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static void set_ram_command(unsigned command)
|
||||
{
|
||||
unsigned char byte;
|
||||
command &= 0x7;
|
||||
pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76, &byte);
|
||||
byte &= 0x1f;
|
||||
byte |= (command << 5);
|
||||
pcibios_write_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76, byte);
|
||||
printk_debug("set_ram_command 0x76.b=%02x\n", byte);
|
||||
}
|
||||
|
||||
#define RAM_COMMAND_NONE 0x0
|
||||
#define RAM_COMMAND_NOOP 0x1
|
||||
#define RAM_COMMAND_PRECHARGE 0x2
|
||||
#define RAM_COMMAND_MRS 0x3
|
||||
#define RAM_COMMAND_CBR 0x4
|
||||
|
||||
void sdram_set_command_none(void)
|
||||
{
|
||||
set_ram_command(RAM_COMMAND_NONE);
|
||||
}
|
||||
void sdram_set_command_noop(void)
|
||||
{
|
||||
set_ram_command(RAM_COMMAND_NOOP);
|
||||
}
|
||||
void sdram_set_command_precharge(void)
|
||||
{
|
||||
set_ram_command(RAM_COMMAND_PRECHARGE);
|
||||
}
|
||||
|
||||
static unsigned long dimm_base(int n)
|
||||
{
|
||||
unsigned char byte;
|
||||
unsigned long result;
|
||||
if (n == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x60 + (n - 1), &byte);
|
||||
result = byte;
|
||||
result <<= 23;
|
||||
return result;
|
||||
}
|
||||
|
||||
static void dimms_read(unsigned long offset)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < 8; i++) {
|
||||
unsigned long dummy;
|
||||
unsigned long addr;
|
||||
unsigned long next_base;
|
||||
|
||||
next_base = dimm_base(i +1);
|
||||
addr = dimm_base(i);
|
||||
if (addr == next_base) {
|
||||
continue;
|
||||
}
|
||||
addr += offset;
|
||||
printk_debug("Reading 0x%08x\n", addr);
|
||||
dummy = RAM(unsigned long, addr);
|
||||
printk_debug("Reading 0x%08x\n", addr ^ 0xddf8);
|
||||
dummy = RAM(unsigned long, addr ^ 0xdff8);
|
||||
printk_debug("Read 0x%08x 0x%08x\n", addr , addr ^ 0xddf8);
|
||||
}
|
||||
}
|
||||
|
||||
void sdram_set_command_cbr(void)
|
||||
{
|
||||
set_ram_command(RAM_COMMAND_CBR);
|
||||
}
|
||||
|
||||
void sdram_assert_command(void)
|
||||
{
|
||||
dimms_read(0x400);
|
||||
}
|
||||
|
||||
void sdram_set_mode_register(void)
|
||||
{
|
||||
unsigned char byte;
|
||||
unsigned cas_mode;
|
||||
set_ram_command(RAM_COMMAND_MRS);
|
||||
pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x76, &byte);
|
||||
cas_mode = byte & 0x4;
|
||||
cas_mode ^= 4;
|
||||
cas_mode <<= 2;
|
||||
cas_mode |= 0x2a;
|
||||
cas_mode <<= 3;
|
||||
dimms_read(cas_mode);
|
||||
}
|
||||
|
||||
void sdram_enable_refresh(void)
|
||||
{
|
||||
spd_enable_refresh();
|
||||
}
|
||||
|
||||
|
||||
unsigned long sdram_get_ecc_size_bytes(void)
|
||||
{
|
||||
unsigned char byte;
|
||||
unsigned long size;
|
||||
/* FIXME handle the no ram case. */
|
||||
/* Read the RAM SIZE */
|
||||
pcibios_read_config_byte(I440GX_BUS, I440GX_DEVFN, 0x67, &byte);
|
||||
/* Convert it to bytes */
|
||||
size = byte;
|
||||
size <<= 23;
|
||||
#if !USE_ECC
|
||||
size = 0;
|
||||
#endif
|
||||
return size;
|
||||
}
|
|
@ -783,7 +783,7 @@ refresh_rates:
|
|||
#if USE_SPD
|
||||
spd_enable_refresh:
|
||||
/* Find the first dimm and assume the rest are the same */
|
||||
/* Load the smbus device and port int %ebx */
|
||||
/* Load the smbus device and port into %ebx */
|
||||
movl $((12 << 8) | SMBUS_MEM_DEVICE_0), %ebx
|
||||
1: CALLSP(smbus_read_byte)
|
||||
jz 2f
|
||||
|
@ -798,7 +798,7 @@ spd_enable_refresh:
|
|||
|
||||
spd_enable_refresh_out:
|
||||
cmpb $0x06, %al /* see if the ram refresh is a supported one */
|
||||
ja 1f
|
||||
jae 1f
|
||||
addl $refresh_rates, %eax /* convert SPD refresh rates to 440GX refresh rates */
|
||||
movb (%eax), %cl
|
||||
jmp 2f
|
||||
|
|
|
@ -6,5 +6,5 @@
|
|||
*/
|
||||
movl $MCH_RICM, %eax
|
||||
PCI_READ_CONFIG_DWORD
|
||||
testl $RICM_DONE, %eax
|
||||
jnz __cpu_reset
|
||||
testl $RICM_DONE, %eax
|
||||
setnz %al
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include <arch/io.h>
|
||||
#include <printk.h>
|
||||
|
||||
#define RTC_PORT(x) (0x70 + (x))
|
||||
#include <pc80/mc146818rtc.h>
|
||||
|
||||
#define CMOS_READ(addr) ({ \
|
||||
outb_p((addr),RTC_PORT(0)); \
|
||||
|
@ -83,10 +82,6 @@ outb_p((val),RTC_PORT(1)); \
|
|||
/**********************************************************************/
|
||||
|
||||
|
||||
/* On PCs, the checksum is built only over bytes 16..45 */
|
||||
#define PC_CKS_RANGE_START 16
|
||||
#define PC_CKS_RANGE_END 45
|
||||
#define PC_CKS_LOC 46
|
||||
|
||||
static int rtc_checksum_valid(void)
|
||||
{
|
||||
|
@ -123,32 +118,40 @@ static void rtc_set_checksum(void)
|
|||
#define RTC_CONTROL_DEFAULT (RTC_SQWE | RTC_24H)
|
||||
#define RTC_FREQ_SELECT_DEFAULT (RTC_REF_CLCK_32KHZ | RTC_RATE_1024HZ)
|
||||
#endif
|
||||
void rtc_init(void)
|
||||
void rtc_init(int invalid)
|
||||
{
|
||||
unsigned char x;
|
||||
int cmos_valid;
|
||||
int cmos_invalid, checksum_invalid;
|
||||
/* See if there has been a CMOS power problem. */
|
||||
x = CMOS_READ(RTC_VALID);
|
||||
cmos_valid = !(x & RTC_VRT);
|
||||
cmos_invalid = !(x & RTC_VRT);
|
||||
|
||||
/* See if there is a CMOS checksum error */
|
||||
cmos_valid = rtc_checksum_valid();
|
||||
checksum_invalid = !rtc_checksum_valid();
|
||||
|
||||
if (!cmos_valid) {
|
||||
if (invalid || cmos_invalid || checksum_invalid) {
|
||||
int i;
|
||||
printk_warning("RTC power problem, zeroing cmos\n");
|
||||
for(i = 0x0; i < 128; i++) {
|
||||
printk_warning("RTC:%s%s%s zeroing cmos\n",
|
||||
invalid?" Clear requested":"",
|
||||
cmos_invalid?" Power Problem":"",
|
||||
checksum_invalid?" Checksum invalid":"");
|
||||
CMOS_WRITE(0, 0x01);
|
||||
CMOS_WRITE(0, 0x03);
|
||||
CMOS_WRITE(0, 0x05);
|
||||
for(i = 10; i < 128; i++) {
|
||||
CMOS_WRITE(0, i);
|
||||
}
|
||||
|
||||
/* Now setup a default date of Sat 1 January 2000 */
|
||||
CMOS_WRITE(0, 0x00); /* seconds */
|
||||
CMOS_WRITE(0, 0x02); /* minutes */
|
||||
CMOS_WRITE(1, 0x04); /* hours */
|
||||
CMOS_WRITE(7, 0x06); /* day of week */
|
||||
CMOS_WRITE(1, 0x07); /* day of month */
|
||||
CMOS_WRITE(1, 0x08); /* month */
|
||||
CMOS_WRITE(0, 0x09); /* year */
|
||||
if (cmos_invalid) {
|
||||
/* Now setup a default date of Sat 1 January 2000 */
|
||||
CMOS_WRITE(0, 0x00); /* seconds */
|
||||
CMOS_WRITE(0, 0x02); /* minutes */
|
||||
CMOS_WRITE(1, 0x04); /* hours */
|
||||
CMOS_WRITE(7, 0x06); /* day of week */
|
||||
CMOS_WRITE(1, 0x07); /* day of month */
|
||||
CMOS_WRITE(1, 0x08); /* month */
|
||||
CMOS_WRITE(0, 0x09); /* year */
|
||||
}
|
||||
}
|
||||
/* Setup the real time clock */
|
||||
CMOS_WRITE(RTC_CONTROL_DEFAULT, RTC_CONTROL);
|
||||
|
|
1
src/ram/Config
Normal file
1
src/ram/Config
Normal file
|
@ -0,0 +1 @@
|
|||
object ramtest.o USE_RAMTEST
|
68
src/ram/ramtest.c
Normal file
68
src/ram/ramtest.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
#include <arch/cache_ram.h>
|
||||
#include <ramtest.h>
|
||||
#include <printk.h>
|
||||
|
||||
void ram_fill(unsigned long start, unsigned long stop)
|
||||
{
|
||||
unsigned long addr;
|
||||
/*
|
||||
* Fill.
|
||||
*/
|
||||
printk_debug("DRAM fill: %08lx-%08lx\n", start, stop);
|
||||
for(addr = start; addr < stop ; addr += 4) {
|
||||
/* Display address being filled */
|
||||
if ((addr & 0xffff) == 0)
|
||||
printk_debug("%08lx\r", addr);
|
||||
RAM(unsigned long, addr) = addr;
|
||||
};
|
||||
/* Display final address */
|
||||
printk_debug("%08lx\nDRAM filled\n", addr);
|
||||
|
||||
|
||||
}
|
||||
|
||||
int ram_verify(unsigned long start, unsigned long stop, int max_errors)
|
||||
{
|
||||
unsigned long addr;
|
||||
int errors = 0;
|
||||
/*
|
||||
* Verify.
|
||||
*/
|
||||
printk_debug("DRAM verify: %08lx-%08lx\n", start, stop);
|
||||
for(addr = start; addr < stop ; addr += 4) {
|
||||
unsigned long value;
|
||||
/* Display address being tested */
|
||||
if ((addr & 0xffff) == 0)
|
||||
printk_debug("%08lx\r", addr);
|
||||
value = RAM(unsigned long, addr);
|
||||
if (value != addr) {
|
||||
if (++errors <= max_errors) {
|
||||
/* Display address with error */
|
||||
printk_err("%08lx:%08lx\n", addr, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Display final address */
|
||||
printk_debug("%08lx\nDRAM verified %d/%d errors\n",
|
||||
addr, errors, (stop - start)/4);
|
||||
return errors;
|
||||
}
|
||||
|
||||
|
||||
int ramcheck(unsigned long start, unsigned long stop, int max_errors)
|
||||
{
|
||||
int result;
|
||||
/*
|
||||
* This is much more of a "Is my DRAM properly configured?"
|
||||
* test than a "Is my DRAM faulty?" test. Not all bits
|
||||
* are tested. -Tyson
|
||||
*/
|
||||
printk_debug("Testing DRAM : %08lx-%08lx\n",
|
||||
start, stop);
|
||||
|
||||
ram_fill(start, stop);
|
||||
result = ram_verify(start, stop, max_errors);
|
||||
printk_debug("Done.\n");
|
||||
return result;
|
||||
}
|
||||
|
4
src/sdram/Config
Normal file
4
src/sdram/Config
Normal file
|
@ -0,0 +1,4 @@
|
|||
object generic_sdram.o USE_GENERIC_SDRAM
|
||||
object generic_sdram_enable.o USE_GENERIC_SDRAM_ENABLE
|
||||
object generic_dump_spd.o USE_GENERIC_DUMP_SPD
|
||||
object generic_zero_ecc_sdram.o USE_GENERIC_ZERO_ECC_SDRAM
|
28
src/sdram/generic_dump_spd.c
Normal file
28
src/sdram/generic_dump_spd.c
Normal file
|
@ -0,0 +1,28 @@
|
|||
#include <printk.h>
|
||||
#include <smbus.h>
|
||||
|
||||
void dump_spd_registers(void)
|
||||
{
|
||||
unsigned device;
|
||||
device = SMBUS_MEM_DEVICE_START;
|
||||
printk_debug("\n");
|
||||
while(device <= SMBUS_MEM_DEVICE_END) {
|
||||
int status = 0;
|
||||
int i;
|
||||
printk_debug("dimm %02x", device);
|
||||
for(i = 0; (i < 256) && (status == 0); i++) {
|
||||
unsigned char byte;
|
||||
if ((i % 20) == 0) {
|
||||
printk_debug("\n%3d: ", i);
|
||||
}
|
||||
status = smbus_read_byte(device, i, &byte);
|
||||
if (status != 0) {
|
||||
printk_debug("bad device\n");
|
||||
continue;
|
||||
}
|
||||
printk_debug("%02x ", byte);
|
||||
}
|
||||
device += SMBUS_MEM_DEVICE_INC;
|
||||
printk_debug("\n");
|
||||
}
|
||||
}
|
36
src/sdram/generic_sdram.c
Normal file
36
src/sdram/generic_sdram.c
Normal file
|
@ -0,0 +1,36 @@
|
|||
#include <sdram.h>
|
||||
#include <printk.h>
|
||||
|
||||
void sdram_no_memory(void)
|
||||
{
|
||||
printk_err("No memory!!\n");
|
||||
while(1) ;
|
||||
}
|
||||
|
||||
/* Setup SDRAM */
|
||||
void sdram_initialize(void)
|
||||
{
|
||||
printk_debug("Ram1\n");
|
||||
/* Set the registers we can set once to reasonable values */
|
||||
sdram_set_registers();
|
||||
|
||||
printk_debug("Ram2\n");
|
||||
/* Now setup those things we can auto detect */
|
||||
sdram_set_spd_registers();
|
||||
|
||||
printk_debug("Ram3\n");
|
||||
/* Now that everything is setup enable the SDRAM.
|
||||
* Some chipsets do the work for use while on others
|
||||
* we need to it by hand.
|
||||
*/
|
||||
sdram_enable();
|
||||
|
||||
printk_debug("Ram4\n");
|
||||
sdram_first_normal_reference();
|
||||
|
||||
printk_debug("Ram5\n");
|
||||
sdram_enable_refresh();
|
||||
sdram_special_finishup();
|
||||
|
||||
printk_debug("Ram6\n");
|
||||
}
|
51
src/sdram/generic_sdram_enable.c
Normal file
51
src/sdram/generic_sdram_enable.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
#include <sdram.h>
|
||||
#include <delay.h>
|
||||
#include <printk.h>
|
||||
|
||||
void sdram_enable(void)
|
||||
{
|
||||
printk_debug("Ram Enable 1\n");
|
||||
|
||||
/* noop command */
|
||||
sdram_set_command_noop();
|
||||
udelay(200);
|
||||
sdram_assert_command();
|
||||
|
||||
/* Precharge all */
|
||||
sdram_set_command_precharge();
|
||||
sdram_assert_command();
|
||||
|
||||
/* wait until the all banks idle state... */
|
||||
printk_debug("Ram Enable 2\n");
|
||||
|
||||
/* Now we need 8 AUTO REFRESH / CBR cycles to be performed */
|
||||
|
||||
sdram_set_command_cbr();
|
||||
sdram_assert_command();
|
||||
sdram_assert_command();
|
||||
sdram_assert_command();
|
||||
sdram_assert_command();
|
||||
sdram_assert_command();
|
||||
sdram_assert_command();
|
||||
sdram_assert_command();
|
||||
sdram_assert_command();
|
||||
|
||||
printk_debug("Ram Enable 3\n");
|
||||
|
||||
/* mode register set */
|
||||
sdram_set_mode_register();
|
||||
/* MAx[14:0] lines,
|
||||
* MAx[2:0 ] 010 == burst mode of 4
|
||||
* MAx[3:3 ] 1 == interleave wrap type
|
||||
* MAx[4:4 ] == CAS# latency bit
|
||||
* MAx[6:5 ] == 01
|
||||
* MAx[12:7] == 0
|
||||
*/
|
||||
|
||||
printk_debug("Ram Enable 4\n");
|
||||
|
||||
/* normal operation */
|
||||
sdram_set_command_none();
|
||||
|
||||
printk_debug("Ram Enable 5\n");
|
||||
}
|
101
src/sdram/generic_zero_ecc_sdram.c
Normal file
101
src/sdram/generic_zero_ecc_sdram.c
Normal file
|
@ -0,0 +1,101 @@
|
|||
#include <sdram.h>
|
||||
#include <arch/cache_ram.h>
|
||||
#include <printk.h>
|
||||
#include <bitops.h>
|
||||
#include <cpu/p6/mtrr.h>
|
||||
#include <string.h>
|
||||
|
||||
#if 0
|
||||
void sdram_initialize_ecc(void)
|
||||
{
|
||||
unsigned long size;
|
||||
void *start_addr;
|
||||
printk_debug("ecc_ram_1\n");
|
||||
size = sdram_get_ecc_size_bytes();
|
||||
|
||||
/* If we don't have an ECC SDRAM size skip the zeroing */
|
||||
if (size > 0) {
|
||||
/* Compute the next greater power of two memory size,
|
||||
* to use in the mtrrs */
|
||||
unsigned long bits;
|
||||
unsigned long mtrr_size;
|
||||
bits = log2(size);
|
||||
/* See if I need to round up */
|
||||
if (size & ((1 << bits) -1)) {
|
||||
bits++;
|
||||
}
|
||||
mtrr_size = (1 << bits);
|
||||
|
||||
/* Set caching on all of memory into write-combining mode.
|
||||
* So we can zero it quickly.
|
||||
*/
|
||||
set_var_mtrr(0, 0, mtrr_size, MTRR_TYPE_WRCOMB);
|
||||
|
||||
/* Now zero the memory */
|
||||
printk_debug("ecc_ram_2\n");
|
||||
#if defined(HAVE_PC80_MEMORY_HOLE) || 1
|
||||
printk_debug("zeroing 0 - 640K\n");
|
||||
start_addr = RAM_ADDR(0);
|
||||
memset(start_addr, 0, 640*1024);
|
||||
printk_debug("zeroing 1M - %dM\n", size/(1024*1024));
|
||||
start_addr = RAM_ADDR(1024*1024);
|
||||
memset(start_addr, 0, size - (1024*1024));
|
||||
#else
|
||||
printk_debug("zeroing 0 - 0x%08x\n", size);
|
||||
start_addr = RAM_ADDR(0);
|
||||
memset(start_addr, 0, size);
|
||||
#endif
|
||||
printk_debug("ecc_ram_3\n");
|
||||
/* Fully disable caching on ram again. */
|
||||
set_var_mtrr(0, 0, 0, MTRR_TYPE_UNCACHABLE);
|
||||
}
|
||||
printk_debug("ecc_ram_4\n");
|
||||
|
||||
}
|
||||
#else
|
||||
static void ram_clear(unsigned long start, unsigned long stop)
|
||||
{
|
||||
#if 0
|
||||
unsigned long addr;
|
||||
/*
|
||||
* Fill.
|
||||
*/
|
||||
printk_debug("DRAM clear: %08lx-%08lx\n", start, stop);
|
||||
for(addr = start; addr < stop ; addr += 4) {
|
||||
/* Display address being filled */
|
||||
if ((addr & 0xffff) == 0)
|
||||
printk_debug("%08lx\r", addr);
|
||||
RAM(unsigned long, addr) = 0;
|
||||
};
|
||||
/* Display final address */
|
||||
printk_debug("%08lx\nDRAM cleared\n", addr);
|
||||
#else
|
||||
printk_debug("DRAM clear: %08lx-%08lx\n", start, stop);
|
||||
__asm__ volatile(
|
||||
"cld\n\t"
|
||||
"rep stosl\n\t"
|
||||
:
|
||||
: "a" (0), "D" (RAM_ADDR(start)), "c" ((stop - start)/4)
|
||||
);
|
||||
#endif
|
||||
}
|
||||
|
||||
void sdram_initialize_ecc(void)
|
||||
{
|
||||
unsigned long size;
|
||||
printk_debug("stupid_ecc_ram_1\n");
|
||||
size = sdram_get_ecc_size_bytes();
|
||||
|
||||
/* If we don't have an ECC SDRAM size skip the zeroing */
|
||||
if (size > 0) {
|
||||
printk_debug("stupid_ecc_ram_2\n");
|
||||
set_var_mtrr(0, 0, size, MTRR_TYPE_WRCOMB);
|
||||
printk_debug("stupid_ecc_ram_3\n");
|
||||
ram_clear(0, 640*1024);
|
||||
ram_clear(1024*1024, size);
|
||||
};
|
||||
printk_debug("stupid_ecc_ram_4\n");
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -57,7 +57,7 @@ ecc_ram_initialize:
|
|||
cld
|
||||
|
||||
#if !defined(HAVE_PC80_MEMORY_HOLE)
|
||||
/* The 640KB - 1MB memory should not be enabled at this point. */
|
||||
/* The 640KB - 1MB memory hole should not be enabled at this point. */
|
||||
xorl %eax, %eax
|
||||
xorl %edi, %edi
|
||||
movl %ebp, %ecx
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
#define PCI_DMA_CFG 0x90
|
||||
#define SERIRQ_CNTL 0x64
|
||||
#define GEN_CNTL 0xd0
|
||||
#define GEN_STS 0xd4
|
||||
#define GEN_PMCON_3 0xa4
|
||||
|
||||
|
||||
#define RTC_BUS 0
|
||||
#define RTC_DEVFN ((0x1f << 3) + 0)
|
||||
#define RTC_FAILED (1 <<2)
|
||||
|
||||
|
||||
#define SMBUS_BUS 0
|
||||
#define SMBUS_DEVFN ((0x1f << 3) + 3)
|
||||
|
|
|
@ -2,3 +2,8 @@ object nvram.o
|
|||
object ich2_ioapic.o
|
||||
object ich2_lpc.o
|
||||
object ich2_ide.o
|
||||
object ich2_reset.o
|
||||
object ich2_smbus.o
|
||||
object ich2_cpu.o
|
||||
object ich2_rtc.o
|
||||
object ich2_power.o
|
||||
|
|
90
src/southbridge/intel/82801/cmos_failover.inc
Normal file
90
src/southbridge/intel/82801/cmos_failover.inc
Normal file
|
@ -0,0 +1,90 @@
|
|||
/* The algorithm is as follows:
|
||||
*
|
||||
* Step 1: Test for cpu reset
|
||||
* That is, did I just boot or is this a later boot since power on.
|
||||
* The result of this test in %al
|
||||
* %al == 1 -- We are rebooting
|
||||
* %al == 0 -- This is the initial boot
|
||||
*
|
||||
* Step 2: Cpu filter
|
||||
* On an initial boot if we are not the bootstrap CPU go to
|
||||
* sleep.
|
||||
*
|
||||
* Step 3: Test for CMOS validity.
|
||||
* On an initial boot if the CMOS checksum or the CMOS error
|
||||
* condition is signaled clear the CMOS ram.
|
||||
*
|
||||
* Step 4: Test for which copy of linuxbios to boot.
|
||||
* We use 2 bits of CMOS ram.
|
||||
* Bit 0: Initial boot direction
|
||||
* 0 - Boot the failsafe image.
|
||||
* 1 - Boot the other image.
|
||||
* Bit 1: Reboot direction
|
||||
* 0 - Boot the failsafe image.
|
||||
* 1 - Boot the other image.
|
||||
*
|
||||
* On initial boot we read bit0, and write it to bit1, and clear
|
||||
* bit0.
|
||||
*
|
||||
* On a reboot the bits are not touched.
|
||||
*
|
||||
* Then the appropriate image is jumped to.
|
||||
*
|
||||
*
|
||||
*/
|
||||
#include "82801.h"
|
||||
#include <pc80/mc146818rtc.h>
|
||||
#include <part/fallback_boot.h>
|
||||
|
||||
|
||||
/* Intel systems magically stop the second cpu in hardware */
|
||||
testb %al, %al
|
||||
jz __failover_boot
|
||||
|
||||
__failover_reset:
|
||||
movb $RTC_BOOT_BYTE, %al
|
||||
outb %al, $0x70
|
||||
inb $0x71, %al
|
||||
testb $(1<<1), %al
|
||||
jnz __normal_image
|
||||
jmp __cpu_reset
|
||||
|
||||
|
||||
__failover_boot:
|
||||
/* See if the cmos clear jumper has been set */
|
||||
movl $((RTC_DEVFN << 8) | GEN_PMCON_3), %eax
|
||||
PCI_READ_CONFIG_DWORD
|
||||
testl $RTC_FAILED, %eax
|
||||
jz __rtc_ok
|
||||
|
||||
/* There are no impossible values, no checksums
|
||||
* so just trust whatever value we have in the
|
||||
* cmos.
|
||||
*/
|
||||
__rtc_failed:
|
||||
movb $RTC_BOOT_BYTE, %al
|
||||
outb %al, $0x70
|
||||
xorb %al, %al
|
||||
outb %al, $0x71
|
||||
jmp __rtc_ok
|
||||
|
||||
/* The byte is o.k. see where to go */
|
||||
__rtc_ok:
|
||||
movb $RTC_BOOT_BYTE, %al
|
||||
outb %al, $0x70
|
||||
inb $0x71, %al
|
||||
|
||||
/* Transfer the boot bit from bit 0 to bit 1.
|
||||
* And clear bit 0 so that unless we say it works we
|
||||
* fallback to the other bios image immediately.
|
||||
*/
|
||||
movb %al, %bl
|
||||
andb $0xfc, %al
|
||||
andb $1, %bl
|
||||
shlb %bl
|
||||
orb %bl, %al
|
||||
outb %al, $0x71
|
||||
|
||||
testb $(1<<1), %al
|
||||
jnz __normal_image
|
||||
|
21
src/southbridge/intel/82801/ich2_cpu.c
Normal file
21
src/southbridge/intel/82801/ich2_cpu.c
Normal file
|
@ -0,0 +1,21 @@
|
|||
#include <pci.h>
|
||||
#include <pci_ids.h>
|
||||
#include <southbridge/intel/82801.h>
|
||||
#include <printk.h>
|
||||
#include "82801.h"
|
||||
|
||||
void ich2_set_cpu_multiplier(unsigned multiplier)
|
||||
{
|
||||
u32 dword;
|
||||
struct pci_dev *dev;
|
||||
dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_1F0, 0);
|
||||
if (!dev) {
|
||||
printk_err("Cannot find device %08x:%08x\n",
|
||||
PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_1F0);
|
||||
return;
|
||||
}
|
||||
pci_read_config_dword(dev, GEN_STS, &dword);
|
||||
dword &= ~((1 << 12) - (1 << 8));
|
||||
dword |= (multiplier & 0xf) << 8;
|
||||
pci_write_config_dword(dev, GEN_STS, dword);
|
||||
}
|
22
src/southbridge/intel/82801/ich2_power.c
Normal file
22
src/southbridge/intel/82801/ich2_power.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include <southbridge/intel/82801.h>
|
||||
#include <pci.h>
|
||||
#include <pci_ids.h>
|
||||
#include <printk.h>
|
||||
#include "82801.h"
|
||||
|
||||
void ich2_power_after_power_fail(int on)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
unsigned char byte;
|
||||
dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_1F0, 0);
|
||||
if (!dev) {
|
||||
return;
|
||||
}
|
||||
/* FIXME this doesn't work! */
|
||||
/* Which state do we want to goto after g3 (power restored)?
|
||||
* 0 == S0 Full On
|
||||
* 1 == S5 Soft Off
|
||||
*/
|
||||
pci_write_config_byte(dev, GEN_PMCON_3, on?0:1);
|
||||
printk_info("set power %s after power fail\n", on?"on":"off");
|
||||
}
|
9
src/southbridge/intel/82801/ich2_reset.c
Normal file
9
src/southbridge/intel/82801/ich2_reset.c
Normal file
|
@ -0,0 +1,9 @@
|
|||
#include <arch/io.h>
|
||||
#include <southbridge/intel/82801.h>
|
||||
|
||||
void ich2_hard_reset(void)
|
||||
{
|
||||
/* Try rebooting through port 0xcf9 */
|
||||
outb((0 <<3)|(1<<2)|(1<<1), 0xcf9);
|
||||
}
|
||||
|
23
src/southbridge/intel/82801/ich2_rtc.c
Normal file
23
src/southbridge/intel/82801/ich2_rtc.c
Normal file
|
@ -0,0 +1,23 @@
|
|||
#include <southbridge/intel/82801.h>
|
||||
#include <pc80/mc146818rtc.h>
|
||||
#include <pci.h>
|
||||
#include <pci_ids.h>
|
||||
#include <printk.h>
|
||||
#include "82801.h"
|
||||
|
||||
|
||||
void ich2_rtc_init(void)
|
||||
{
|
||||
unsigned char byte;
|
||||
u32 dword;
|
||||
int rtc_failed;
|
||||
pcibios_read_config_byte(RTC_BUS, RTC_DEVFN, GEN_PMCON_3, &byte);
|
||||
rtc_failed = byte & RTC_FAILED;
|
||||
if (rtc_failed) {
|
||||
byte &= ~(1 << 1); /* preserve the power fail state */
|
||||
pcibios_write_config_byte(RTC_BUS, RTC_DEVFN, GEN_PMCON_3, &byte);
|
||||
}
|
||||
pcibios_read_config_dword(RTC_BUS, RTC_DEVFN, GEN_STS, &dword);
|
||||
rtc_failed |= dword & (1 << 2);
|
||||
rtc_init(rtc_failed);
|
||||
}
|
121
src/southbridge/intel/82801/ich2_smbus.c
Normal file
121
src/southbridge/intel/82801/ich2_smbus.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
#include <smbus.h>
|
||||
#include <arch/io.h>
|
||||
#include <pci.h>
|
||||
#include <southbridge/intel/82801.h>
|
||||
#include "82801.h"
|
||||
|
||||
|
||||
#define SMBUS_IO_BASE 0x1000
|
||||
|
||||
#define SMBHSTSTAT 0x0
|
||||
#define SMBHSTCTL 0x2
|
||||
#define SMBHSTCMD 0x3
|
||||
#define SMBXMITADD 0x4
|
||||
#define SMBHSTDAT0 0x5
|
||||
#define SMBHSTDAT1 0x6
|
||||
#define SMBBLKDAT 0x7
|
||||
#define SMBTRNSADD 0x9
|
||||
#define SMBSLVDATA 0xa
|
||||
#define SMLINK_PIN_CTL 0xe
|
||||
#define SMBUS_PIN_CTL 0xf
|
||||
|
||||
void smbus_setup(void)
|
||||
{
|
||||
pcibios_write_config_dword(SMBUS_BUS, SMBUS_DEVFN, 0x20, SMBUS_IO_BASE | 1);
|
||||
pcibios_write_config_byte(SMBUS_BUS, SMBUS_DEVFN, 0x40, 1);
|
||||
pcibios_write_config_word(SMBUS_BUS, SMBUS_DEVFN, 0x4, 1);
|
||||
|
||||
/* Disable interrupt generation */
|
||||
outb(0, SMBUS_IO_BASE + SMBHSTCTL);
|
||||
}
|
||||
|
||||
static void smbus_wait_until_ready(void)
|
||||
{
|
||||
while((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
|
||||
/* nop */
|
||||
}
|
||||
}
|
||||
|
||||
static void smbus_wait_until_done(void)
|
||||
{
|
||||
unsigned char byte;
|
||||
do {
|
||||
byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
|
||||
} while((byte &1) == 1);
|
||||
while( (byte & ~((1<<6)|(1<<0))) == 0) {
|
||||
byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void smbus_print_error(unsigned char host_status_register)
|
||||
{
|
||||
|
||||
printk_debug("smbus_error: 0x%02x\n", host_status_register);
|
||||
if (host_status_register & (1 << 7)) {
|
||||
printk_debug("Byte Done Status\n");
|
||||
}
|
||||
if (host_status_register & (1 << 6)) {
|
||||
printk_debug("In Use Status\n");
|
||||
}
|
||||
if (host_status_register & (1 << 5)) {
|
||||
printk_debug("SMBus Alert Status\n");
|
||||
}
|
||||
if (host_status_register & (1 << 4)) {
|
||||
printk_debug("Interrup/SMI# was Failed Bus Transaction\n");
|
||||
}
|
||||
if (host_status_register & (1 << 3)) {
|
||||
printk_debug("Bus Error\n");
|
||||
}
|
||||
if (host_status_register & (1 << 2)) {
|
||||
printk_debug("Device Error\n");
|
||||
}
|
||||
if (host_status_register & (1 << 1)) {
|
||||
printk_debug("Interrupt/SMI# was Successful Completion\n");
|
||||
}
|
||||
if (host_status_register & (1 << 0)) {
|
||||
printk_debug("Host Busy\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
|
||||
{
|
||||
unsigned char host_status_register;
|
||||
unsigned char byte;
|
||||
|
||||
smbus_wait_until_ready();
|
||||
|
||||
/* setup transaction */
|
||||
/* disable interrupts */
|
||||
outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
|
||||
/* set the device I'm talking too */
|
||||
outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBXMITADD);
|
||||
/* set the command/address... */
|
||||
outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
|
||||
/* set up for a byte data read */
|
||||
outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
|
||||
|
||||
/* clear any lingering errors, so the transaction will run */
|
||||
outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
|
||||
|
||||
/* clear the data byte...*/
|
||||
outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
|
||||
|
||||
/* start the command */
|
||||
outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
|
||||
|
||||
/* poll for transaction completion */
|
||||
smbus_wait_until_done();
|
||||
|
||||
host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
|
||||
|
||||
/* Ignore the In Use Status... */
|
||||
host_status_register &= ~(1 << 6);
|
||||
|
||||
/* read results of transaction */
|
||||
byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
|
||||
|
||||
*result = byte;
|
||||
return host_status_register != 0x02;
|
||||
}
|
|
@ -1 +1,2 @@
|
|||
object southbridge.o
|
||||
object smbus.o USE_PIIX4E_SMBUS
|
||||
|
|
87
src/southbridge/intel/piix4e/smbus.c
Normal file
87
src/southbridge/intel/piix4e/smbus.c
Normal file
|
@ -0,0 +1,87 @@
|
|||
#include <smbus.h>
|
||||
#include <pci.h>
|
||||
#include <arch/io.h>
|
||||
|
||||
#define PM_BUS 0
|
||||
#define PM_DEVFN (PIIX4_DEVFN+3)
|
||||
|
||||
#define SMBUS_IO_BASE 0x1000
|
||||
#define SMBHSTSTAT 0
|
||||
#define SMBHSTCTL 2
|
||||
#define SMBHSTCMD 3
|
||||
#define SMBHSTADD 4
|
||||
#define SMBHSTDAT0 5
|
||||
#define SMBHSTDAT1 6
|
||||
#define SMBBLKDAT 7
|
||||
|
||||
void smbus_enable(void)
|
||||
{
|
||||
/* iobase addr */
|
||||
pcibios_write_config_dword(PM_BUS, PM_DEVFN, 0x90, SMBUS_IO_BASE | 1);
|
||||
/* smbus enable */
|
||||
pcibios_write_config_byte(PM_BUS, PM_DEVFN, 0xd2, (0x4 << 1) | 1);
|
||||
/* iospace enable */
|
||||
pcibios_write_config_word(PM_BUS, PM_DEVFN, 0x4, 1);
|
||||
}
|
||||
|
||||
void smbus_setup(void)
|
||||
{
|
||||
outb(0, SMBUS_IO_BASE + SMBHSTSTAT);
|
||||
}
|
||||
|
||||
static void smbus_wait_until_ready(void)
|
||||
{
|
||||
while((inb(SMBUS_IO_BASE + SMBHSTSTAT) & 1) == 1) {
|
||||
/* nop */
|
||||
}
|
||||
}
|
||||
|
||||
static void smbus_wait_until_done(void)
|
||||
{
|
||||
unsigned char byte;
|
||||
do {
|
||||
byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
|
||||
}
|
||||
while((byte &1) == 1);
|
||||
while( (byte & ~1) == 0) {
|
||||
byte = inb(SMBUS_IO_BASE + SMBHSTSTAT);
|
||||
}
|
||||
}
|
||||
|
||||
int smbus_read_byte(unsigned device, unsigned address, unsigned char *result)
|
||||
{
|
||||
unsigned char host_status_register;
|
||||
unsigned char byte;
|
||||
|
||||
smbus_wait_until_ready();
|
||||
|
||||
/* setup transaction */
|
||||
/* disable interrupts */
|
||||
outb(inb(SMBUS_IO_BASE + SMBHSTCTL) & (~1), SMBUS_IO_BASE + SMBHSTCTL);
|
||||
/* set the device I'm talking too */
|
||||
outb(((device & 0x7f) << 1) | 1, SMBUS_IO_BASE + SMBHSTADD);
|
||||
/* set the command/address... */
|
||||
outb(address & 0xFF, SMBUS_IO_BASE + SMBHSTCMD);
|
||||
/* set up for a byte data read */
|
||||
outb((inb(SMBUS_IO_BASE + SMBHSTCTL) & 0xE3) | (0x2 << 2), SMBUS_IO_BASE + SMBHSTCTL);
|
||||
|
||||
/* clear any lingering errors, so the transaction will run */
|
||||
outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
|
||||
|
||||
/* clear the data byte...*/
|
||||
outb(0, SMBUS_IO_BASE + SMBHSTDAT0);
|
||||
|
||||
/* start the command */
|
||||
outb((inb(SMBUS_IO_BASE + SMBHSTCTL) | 0x40), SMBUS_IO_BASE + SMBHSTCTL);
|
||||
|
||||
/* poll for transaction completion */
|
||||
smbus_wait_until_done();
|
||||
|
||||
host_status_register = inb(SMBUS_IO_BASE + SMBHSTSTAT);
|
||||
|
||||
/* read results of transaction */
|
||||
byte = inb(SMBUS_IO_BASE + SMBHSTDAT0);
|
||||
|
||||
*result = byte;
|
||||
return host_status_register != 0x02;
|
||||
}
|
2
src/superio/generic/Config
Normal file
2
src/superio/generic/Config
Normal file
|
@ -0,0 +1,2 @@
|
|||
object generic_superio.o
|
||||
|
57
src/superio/generic/generic_superio.c
Normal file
57
src/superio/generic/generic_superio.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include <arch/io.h>
|
||||
#include <superio/generic.h>
|
||||
|
||||
void pnp_write_config(unsigned char port,
|
||||
unsigned char value, unsigned char reg)
|
||||
{
|
||||
outb(reg, port);
|
||||
outb(value, port + 1);
|
||||
}
|
||||
|
||||
unsigned char pnp_read_config(unsigned char port, unsigned char reg)
|
||||
{
|
||||
outb(reg, port);
|
||||
return inb(port +1);
|
||||
}
|
||||
|
||||
void pnp_set_logical_device(unsigned char port, int device)
|
||||
{
|
||||
pnp_write_config(port, device, 0x07);
|
||||
}
|
||||
|
||||
void pnp_set_enable(unsigned char port, int enable)
|
||||
{
|
||||
pnp_write_config(port, enable?0x1:0x0, 0x30);
|
||||
}
|
||||
|
||||
int pnp_read_enable(unsigned char port)
|
||||
{
|
||||
return !!pnp_read_config(port, 0x30);
|
||||
}
|
||||
|
||||
void pnp_set_iobase0(unsigned char port, unsigned iobase)
|
||||
{
|
||||
pnp_write_config(port, (iobase >> 8) & 0xff, 0x60);
|
||||
pnp_write_config(port, iobase & 0xff, 0x61);
|
||||
}
|
||||
|
||||
void pnp_set_iobase1(unsigned char port, unsigned iobase)
|
||||
{
|
||||
pnp_write_config(port, (iobase >> 8) & 0xff, 0x62);
|
||||
pnp_write_config(port, iobase & 0xff, 0x63);
|
||||
}
|
||||
|
||||
void pnp_set_irq0(unsigned char port, unsigned irq)
|
||||
{
|
||||
pnp_write_config(port, irq, 0x70);
|
||||
}
|
||||
|
||||
void pnp_set_irq1(unsigned char port, unsigned irq)
|
||||
{
|
||||
pnp_write_config(port, irq, 0x72);
|
||||
}
|
||||
|
||||
void pnp_set_drq(unsigned char port, unsigned drq)
|
||||
{
|
||||
pnp_write_config(port, drq & 0xff, 0x74);
|
||||
}
|
56
src/superio/generic/generic_superio.h
Normal file
56
src/superio/generic/generic_superio.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include <arch/io.h>
|
||||
|
||||
void pnp_write_config(unsigned char port,
|
||||
unsigned char value, unsigned char reg)
|
||||
{
|
||||
outb(reg, port);
|
||||
outb(value, port + 1);
|
||||
}
|
||||
|
||||
unsigned char pnp_read_config(unsigned char port, unsigned char reg)
|
||||
{
|
||||
outb(reg, port);
|
||||
return inb(port +1);
|
||||
}
|
||||
|
||||
void pnp_set_logical_device(unsigned char port, int device)
|
||||
{
|
||||
pnp_write_config(port, device, 0x07);
|
||||
}
|
||||
|
||||
void pnp_set_enable(unsigned char port, int enable)
|
||||
{
|
||||
pnp_write_config(port, enable?0x1:0x0, 0x30);
|
||||
}
|
||||
|
||||
int pnp_read_enable(unsigned char port)
|
||||
{
|
||||
return !!pnp_read_config(port, 0x30);
|
||||
}
|
||||
|
||||
void pnp_set_iobase0(unsigned char port, unsigned iobase)
|
||||
{
|
||||
pnp_write_config(port, (iobase >> 8) & 0xff, 0x60);
|
||||
pnp_write_config(port, iobase & 0xff, 0x61);
|
||||
}
|
||||
|
||||
void set_iobase1(unsigned char port, unsigned iobase)
|
||||
{
|
||||
pnp_write_config(port, (iobase >> 8) & 0xff, 0x62);
|
||||
pnp_write_config(port, iobase & 0xff, 0x63);
|
||||
}
|
||||
|
||||
void set_irq0(unsigned char port, unsigned irq)
|
||||
{
|
||||
pnp_write_config(port, irq, 0x70);
|
||||
}
|
||||
|
||||
void set_irq1(unsigned char port, unsigned irq)
|
||||
{
|
||||
pnp_write_config(port, irq, 0x72);
|
||||
}
|
||||
|
||||
void set_drq(unsigned char port, unsigned drq)
|
||||
{
|
||||
pnp_write_config(port, drq & 0xff, 0x74);
|
||||
}
|
2
src/superio/winbond/w83627hf/Config
Normal file
2
src/superio/winbond/w83627hf/Config
Normal file
|
@ -0,0 +1,2 @@
|
|||
dir /src/superio/generic
|
||||
object w83627hf_power.o
|
|
@ -4,28 +4,16 @@
|
|||
|
||||
|
||||
/* The base address is 0x2e,0x4e depending on config bytes */
|
||||
#include <superio/w83627hf.h>
|
||||
|
||||
#define SIO_INDEX SIO_BASE
|
||||
#define SIO_DATA SIO_BASE+1
|
||||
|
||||
#define SIO_SYSTEM_CLK_INPUT_48MHZ (1<<6)
|
||||
#define SIO_SYSTEM_CLK_INPUT_24MHZ (0<<6)
|
||||
|
||||
#if defined(SIO_SYSTEM_CLK_INPUT)
|
||||
#if (SIO_SYSTEM_CLK_INPUT != SIO_SYSTEM_CLK_INPUT_48MHZ) && (SIO_SYSTEM_CLK_INPUT != SIO_SYSTEM_CLK_INPUT_24MHZ)
|
||||
#error BAD SIO_SYSTEM_CLK_INPUT_PARAMETER
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#define SIO_COM1_DEVICE 2
|
||||
|
||||
#define SIO_ENTER_PNP_MODE() \
|
||||
movb $0x87, %al ; \
|
||||
outb %al, $(SIO_BASE) ; \
|
||||
outb %al, $(SIO_BASE)
|
||||
|
||||
|
||||
#define SIO_EXIT_PNP_MODE() \
|
||||
movb $0xaa, %al ; \
|
||||
outb %al, $(SIO_BASE)
|
||||
|
@ -52,7 +40,7 @@
|
|||
SIO_WRITE_CONFIG((0x84 | SIO_SYSTEM_CLK_INPUT), 0x24)
|
||||
#endif
|
||||
/* enable serial 1 */
|
||||
SIO_SET_LOGICAL_DEVICE(SIO_COM1_DEVICE)
|
||||
SIO_SET_LOGICAL_DEVICE(COM1_DEVICE)
|
||||
SIO_WRITE_CONFIG(1, 0x30)
|
||||
SIO_WRITE_CONFIG(0x3, 0x60)
|
||||
SIO_WRITE_CONFIG(0xf8, 0x61)
|
||||
|
|
|
@ -2,119 +2,51 @@
|
|||
#include <cpu/p5/io.h>
|
||||
#include <serial_subr.h>
|
||||
#include <printk.h>
|
||||
#include <pc80/keyboard.h>
|
||||
#include <superio/generic.h>
|
||||
#include <superio/w83627hf.h>
|
||||
|
||||
#define FLOPPY_DEVICE 0
|
||||
#define PARALLEL_DEVICE 1
|
||||
#define COM1_DEVICE 2
|
||||
#define COM2_DEVICE 3
|
||||
#define KBC_DEVICE 5
|
||||
#define CIR_DEVICE 6
|
||||
#define GAME_PORT_DEVICE 7
|
||||
#define GPIO_PORT2_DEVICE 8
|
||||
#define GPIO_PORT3_DEVICE 9
|
||||
#define ACPI_DEVICE 0xa
|
||||
#define HW_MONITOR_DEVICE 0xb
|
||||
|
||||
|
||||
#define FLOPPY_DEFAULT_IOBASE 0x3f0
|
||||
#define FLOPPY_DEFAULT_IRQ 6
|
||||
#define FLOPPY_DEFAULT_DRQ 2
|
||||
#define PARALLEL_DEFAULT_IOBASE 0x378
|
||||
#define PARALLEL_DEFAULT_IRQ 7
|
||||
#define PARALLEL_DEFAULT_DRQ 4 /* No dma */
|
||||
#define COM1_DEFAULT_IOBASE 0x3f8
|
||||
#define COM1_DEFAULT_IRQ 4
|
||||
#define COM1_DEFAULT_BAUD 115200
|
||||
#define COM2_DEFAULT_IOBASE 0x2f8
|
||||
#define COM2_DEFAULT_IRQ 3
|
||||
#define COM2_DEFAULT_BAUD 115200
|
||||
#define KBC_DEFAULT_IOBASE0 0x60
|
||||
#define KBC_DEFAULT_IOBASE1 0x64
|
||||
#define KBC_DEFAULT_IRQ0 0x1
|
||||
#define KBC_DEFAULT_IRQ1 0xc
|
||||
|
||||
|
||||
static void enter_pnp(struct superio *sio)
|
||||
{
|
||||
outb(0x87, sio->port);
|
||||
outb(0x87, sio->port);
|
||||
}
|
||||
|
||||
static void exit_pnp(struct superio *sio)
|
||||
{
|
||||
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_enable(struct superio *sio, int enable)
|
||||
{
|
||||
write_config(sio, enable?0x1:0x0, 0x30);
|
||||
#if 0
|
||||
if (enable) {
|
||||
printk_debug("enabled superio device: %d\n",
|
||||
read_config(sio, 0x07));
|
||||
}
|
||||
#if defined(SERIAL_CONSOLE)
|
||||
# if !defined(TTYS0_BASE)
|
||||
# define TTYS0_BASE 0x3f8
|
||||
# endif
|
||||
#else
|
||||
#undef TTYS0_BASE
|
||||
#endif
|
||||
|
||||
void w83627hf_enter_pnp(unsigned char port)
|
||||
{
|
||||
outb(0x87, port);
|
||||
outb(0x87, port);
|
||||
}
|
||||
|
||||
static void set_iobase0(struct superio *sio, unsigned iobase)
|
||||
void w83627hf_exit_pnp(unsigned char port)
|
||||
{
|
||||
write_config(sio, (iobase >> 8) & 0xff, 0x60);
|
||||
write_config(sio, iobase & 0xff, 0x61);
|
||||
}
|
||||
outb(0xaa, port);
|
||||
|
||||
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_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 setup_com(struct superio *sio,
|
||||
struct com_ports *com, int device)
|
||||
{
|
||||
int divisor = 115200/com->baud;
|
||||
if ((com->base == TTYS0_BASE) && (!!pnp_read_enable(sio->port) == !!com->enable)) {
|
||||
/* Don't reinitialize the console serial port,
|
||||
* This is especially nasty in SMP.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
printk_debug("Enabling com device: %02x\n", device);
|
||||
printk_debug(" iobase = 0x%04x irq=%d\n", com->base, com->irq);
|
||||
/* Select the device */
|
||||
set_logical_device(sio, device);
|
||||
pnp_set_logical_device(sio->port, device);
|
||||
/* Disable it while it is initialized */
|
||||
set_enable(sio, 0);
|
||||
pnp_set_enable(sio->port, 0);
|
||||
if (com->enable) {
|
||||
set_iobase0(sio, com->base);
|
||||
set_irq0(sio, com->irq);
|
||||
pnp_set_iobase0(sio->port, com->base);
|
||||
pnp_set_irq0(sio->port, com->irq);
|
||||
/* We are initialized so enable the device */
|
||||
set_enable(sio, 1);
|
||||
pnp_set_enable(sio->port, 1);
|
||||
/* Now initialize the com port */
|
||||
uart_init(com->base, divisor);
|
||||
}
|
||||
|
@ -127,14 +59,14 @@ static void setup_floppy(struct superio *sio)
|
|||
unsigned irq = FLOPPY_DEFAULT_IRQ;
|
||||
unsigned drq = FLOPPY_DEFAULT_DRQ;
|
||||
/* Select the device */
|
||||
set_logical_device(sio, FLOPPY_DEVICE);
|
||||
pnp_set_logical_device(sio->port, FLOPPY_DEVICE);
|
||||
/* Disable it while initializing */
|
||||
set_enable(sio, 0);
|
||||
pnp_set_enable(sio->port, 0);
|
||||
if (sio->floppy) {
|
||||
set_iobase0(sio, iobase);
|
||||
set_irq0(sio, irq);
|
||||
set_drq(sio, drq);
|
||||
set_enable(sio, 1);
|
||||
pnp_set_iobase0(sio->port, iobase);
|
||||
pnp_set_irq0(sio->port, irq);
|
||||
pnp_set_drq(sio->port, drq);
|
||||
pnp_set_enable(sio->port, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,14 +77,14 @@ static void setup_parallel(struct superio *sio)
|
|||
unsigned irq = PARALLEL_DEFAULT_IRQ;
|
||||
unsigned drq = PARALLEL_DEFAULT_DRQ;
|
||||
/* Select the device */
|
||||
set_logical_device(sio, PARALLEL_DEVICE);
|
||||
pnp_set_logical_device(sio->port, PARALLEL_DEVICE);
|
||||
/* Disable it while initializing */
|
||||
set_enable(sio, 0);
|
||||
pnp_set_enable(sio->port, 0);
|
||||
if (sio->lpt) {
|
||||
set_iobase0(sio, iobase);
|
||||
set_irq0(sio, irq);
|
||||
set_drq(sio, drq);
|
||||
set_enable(sio, 1);
|
||||
pnp_set_iobase0(sio->port, iobase);
|
||||
pnp_set_irq0(sio->port, irq);
|
||||
pnp_set_drq(sio->port, drq);
|
||||
pnp_set_enable(sio->port, 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,15 +96,15 @@ static void setup_keyboard(struct superio *sio)
|
|||
unsigned irq0 = KBC_DEFAULT_IRQ0;
|
||||
unsigned irq1 = KBC_DEFAULT_IRQ1;
|
||||
/* Select the device */
|
||||
set_logical_device(sio, KBC_DEVICE);
|
||||
pnp_set_logical_device(sio->port, KBC_DEVICE);
|
||||
/* Disable it while initializing */
|
||||
set_enable(sio, 0);
|
||||
pnp_set_enable(sio->port, 0);
|
||||
if (sio->keyboard) {
|
||||
set_iobase0(sio, iobase0);
|
||||
set_iobase1(sio, iobase1);
|
||||
set_irq0(sio, irq0);
|
||||
set_irq1(sio, irq1);
|
||||
set_enable(sio, 1);
|
||||
pnp_set_iobase0(sio->port, iobase0);
|
||||
pnp_set_iobase1(sio->port, iobase1);
|
||||
pnp_set_irq0(sio->port, irq0);
|
||||
pnp_set_irq1(sio->port, irq1);
|
||||
pnp_set_enable(sio->port, 1);
|
||||
/* Initialize the keyboard */
|
||||
pc_keyboard_init();
|
||||
}
|
||||
|
@ -182,10 +114,10 @@ static void setup_keyboard(struct superio *sio)
|
|||
#if 0
|
||||
static void setup_acpi_registers(struct superio *sio)
|
||||
{
|
||||
set_logical_device(sio, ACPI_DEVICE);
|
||||
pnp_set_logical_device(sio->port, ACPI_DEVICE);
|
||||
/* Enable power on after power fail */
|
||||
write_config(sio, (1 << 7)|(0 <<5), 0xe4);
|
||||
set_enable(sio, 1);
|
||||
pnp_write_config(sio->port, (1 << 7)|(0 <<5), 0xe4);
|
||||
pnp_set_enable(sio->port, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -201,7 +133,12 @@ static void enable_devices(struct superio *sio)
|
|||
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);
|
||||
w83627hf_enter_pnp(sio->port);
|
||||
|
||||
#if defined(SIO_SYSTEM_CLK_INPUT)
|
||||
/* Setup the clock input */
|
||||
pnp_write_config(sio->port, (0x84 | SIO_SYSTEM_CLK_INPUT), 0x24);
|
||||
#endif
|
||||
|
||||
/* enable/disable floppy */
|
||||
setup_floppy(sio);
|
||||
|
@ -219,28 +156,28 @@ static void enable_devices(struct superio *sio)
|
|||
setup_keyboard(sio);
|
||||
|
||||
/* enable/disable cir */
|
||||
set_logical_device(sio, CIR_DEVICE);
|
||||
set_enable(sio, sio->cir);
|
||||
pnp_set_logical_device(sio->port, CIR_DEVICE);
|
||||
pnp_set_enable(sio->port, sio->cir);
|
||||
|
||||
/* game */
|
||||
set_logical_device(sio, GAME_PORT_DEVICE);
|
||||
set_enable(sio, sio->game);
|
||||
pnp_set_logical_device(sio->port, GAME_PORT_DEVICE);
|
||||
pnp_set_enable(sio->port, sio->game);
|
||||
|
||||
/* gpio_port2 */
|
||||
set_logical_device(sio, GPIO_PORT2_DEVICE);
|
||||
set_enable(sio, sio->gpio2);
|
||||
pnp_set_logical_device(sio->port, GPIO_PORT2_DEVICE);
|
||||
pnp_set_enable(sio->port, sio->gpio2);
|
||||
|
||||
/* gpio_port3 */
|
||||
set_logical_device(sio, GPIO_PORT3_DEVICE);
|
||||
set_enable(sio, sio->gpio3);
|
||||
pnp_set_logical_device(sio->port, GPIO_PORT3_DEVICE);
|
||||
pnp_set_enable(sio->port, sio->gpio3);
|
||||
|
||||
/* enable/disable acpi */
|
||||
set_logical_device(sio, ACPI_DEVICE);
|
||||
set_enable(sio, sio->acpi);
|
||||
pnp_set_logical_device(sio->port, ACPI_DEVICE);
|
||||
pnp_set_enable(sio->port, sio->acpi);
|
||||
|
||||
/* enable/disable hw monitor */
|
||||
set_logical_device(sio, HW_MONITOR_DEVICE);
|
||||
set_enable(sio, sio->hwmonitor);
|
||||
pnp_set_logical_device(sio->port, HW_MONITOR_DEVICE);
|
||||
pnp_set_enable(sio->port, sio->hwmonitor);
|
||||
|
||||
#if 0
|
||||
/* setup acpi registers so I am certain to get
|
||||
|
@ -249,7 +186,7 @@ static void enable_devices(struct superio *sio)
|
|||
setup_acpi_registers(sio);
|
||||
#endif
|
||||
|
||||
exit_pnp(sio);
|
||||
w83627hf_exit_pnp(sio->port);
|
||||
}
|
||||
|
||||
/* The base address is either 0x2e or 0x4e */
|
||||
|
|
20
src/superio/winbond/w83627hf/w83627hf_power.c
Normal file
20
src/superio/winbond/w83627hf/w83627hf_power.c
Normal file
|
@ -0,0 +1,20 @@
|
|||
#include <superio/generic.h>
|
||||
#include <superio/w83627hf.h>
|
||||
|
||||
void w832627hf_power_after_power_fail(int state)
|
||||
{
|
||||
unsigned char byte;
|
||||
w83627hf_enter_pnp(SIO_BASE);
|
||||
pnp_set_logical_device(SIO_BASE, ACPI_DEVICE);
|
||||
pnp_set_enable(SIO_BASE, 1);
|
||||
|
||||
/* Enable power on after power fail */
|
||||
byte = pnp_read_config(SIO_BASE, 0xe4);
|
||||
byte &= ~(3 << 5);
|
||||
byte |= (state & 3) << 5;
|
||||
pnp_write_config(SIO_BASE, byte, 0xe4);
|
||||
|
||||
w83627hf_exit_pnp(SIO_BASE);
|
||||
}
|
||||
|
||||
|
Loading…
Add table
Reference in a new issue