mirror of
https://github.com/fail0verflow/switch-coreboot.git
synced 2025-05-04 01:39:18 -04:00
Lots and Lots of changes. Mainly bugfixes for the supermicro p4dc6,
and a bunch of generic changes. - Started playing with automatic scanning memory for LinuxBIOS tables. - Converted the fill_inbuf drivers to stream drivers. This allows for pure data copying operations to be faster, and it allows skipping of unneeded data on platforms that support it. - Added a section .rodata.streams for the stream driver control structures. This is preparation for building a bootloader that shares source code with LinuxBIOS. - Added a driver command to NLBConfig.py for objects that should always be linked into LinuxBIOS if they are compiled at all. - Moved the boot_successful logic down into the guts of the bootloaders. - Modified the ip style checksum logic so it isn't specific to uniform boot headers... - Added a function ndelay that uses the RTC (this is i786 specific for now). - Added a function to delay in seconds for the braindead harddrive spinup logic. - Added a floppy stream driver. - Added a ide stream driver. - Broke out the ram initialization for the p4dc6 into multiple c files. - Stupidly adapted linuxbiosmain and do_inflate to the new stream interface. get_byte is now a slow function call so it might be able to use some optimization. - Updated the ELF bootloader to the new stream interface and adding a ELF header scanning function so we can boot off of harddrives and not smash their partition tables. - Removed some bogus unlook ahead code from inflate.c - Fixed a problem where we did not enable I/O resources on VGA compatible chips. This caused a trident card to lock up the system when it's memory mapped resources were enabled. - Correctly set up nested pci busses. Before this a pci bus behind a pci bus would not get enabled. - Config changes to the p4dc6 - Added more interrupt sources to the p4dc6 interrupt table - Converted all of the inbuf drivers to stream drivers. All have good conversions except the doc_millenium.
This commit is contained in:
parent
b5516dc586
commit
cb232f1e04
38 changed files with 3398 additions and 295 deletions
|
@ -11,6 +11,7 @@
|
|||
|
||||
static struct {
|
||||
struct uniform_boot_header header;
|
||||
struct linuxbios_header lb_header;
|
||||
struct {
|
||||
struct {
|
||||
struct ube_memory memory;
|
||||
|
@ -27,6 +28,14 @@ static struct {
|
|||
.env = (unsigned long)&ube_all.env,
|
||||
.env_bytes = sizeof(ube_all.env),
|
||||
},
|
||||
.lb_header = {
|
||||
.signature = { 'L', 'B', 'I', 'O' },
|
||||
.header_bytes = sizeof(ube_all.lb_header),
|
||||
.header_checksum = 0,
|
||||
.env_bytes = sizeof(ube_all.env),
|
||||
.env_checksum = 0,
|
||||
.env_entries = 0,
|
||||
},
|
||||
.env = {
|
||||
.mem = {
|
||||
.memory = {
|
||||
|
@ -65,6 +74,11 @@ void *get_ube_pointer(unsigned long totalram)
|
|||
ube_all.header.header_checksum = 0;
|
||||
ube_all.header.header_checksum =
|
||||
uniform_boot_compute_header_checksum(&ube_all.header);
|
||||
ube_all.lb_header.env_entries = 1; /* FIXME remove this hardcode.. */
|
||||
ube_all.lb_header.env_checksum =
|
||||
compute_checksum(&ube_all.env, sizeof(ube_all.env));
|
||||
ube_all.lb_header.header_checksum =
|
||||
compute_checksum(&ube_all.lb_header, sizeof(ube_all.lb_header));
|
||||
return &ube_all.header;
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,9 @@ SECTIONS
|
|||
}
|
||||
.rodata (.) : {
|
||||
_rodata = .;
|
||||
streams = . ;
|
||||
*(.rodata.streams)
|
||||
estreams = .;
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
_erodata = .;
|
||||
|
|
|
@ -49,7 +49,6 @@ 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>
|
||||
|
@ -290,9 +289,6 @@ 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.
|
||||
|
|
|
@ -16,7 +16,7 @@ makerule ldoptions : Makefile.settings ; perl -e 'foreach $$var (split(" ", $$EN
|
|||
|
||||
makerule linuxbios.strip: linuxbios ; objcopy -O binary linuxbios linuxbios.strip
|
||||
|
||||
makerule linuxbios.o : crt0.o linuxbios.a $(LIBGCC_FILE_NAME) ; $(CC) -nostdlib -r -o $@ crt0.o linuxbios.a $(LIBGCC_FILE_NAME)
|
||||
makerule linuxbios.o : crt0.o $(DRIVERS-1) linuxbios.a $(LIBGCC_FILE_NAME) ; $(CC) -nostdlib -r -o $@ crt0.o $(DRIVERS-1) linuxbios.a $(LIBGCC_FILE_NAME)
|
||||
|
||||
|
||||
makerule linuxbios: linuxbios.o ldscript.ld ; $(CC) -nostdlib -nostartfiles -static -o $@ -T ldscript.ld linuxbios.o
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
option i786
|
||||
|
||||
object delay_i786.o
|
||||
|
|
18
src/cpu/i786/delay_i786.c
Normal file
18
src/cpu/i786/delay_i786.c
Normal file
|
@ -0,0 +1,18 @@
|
|||
#include <cpu/p6/msr.h>
|
||||
|
||||
void ndelay(unsigned long ns)
|
||||
{
|
||||
unsigned long long count;
|
||||
unsigned long long stop;
|
||||
unsigned long long ticks;
|
||||
|
||||
/* FIXME calibrate this... don't just estimage 2Ghz */
|
||||
ticks = ns << 1;
|
||||
rdtscll(count);
|
||||
stop = ticks + count;
|
||||
while(stop > count) {
|
||||
rdtscll(count);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3,5 +3,6 @@
|
|||
|
||||
void udelay(int usecs);
|
||||
void mdelay(int msecs);
|
||||
void delay(int secs);
|
||||
|
||||
#endif /* DELAY_H */
|
||||
|
|
9
src/include/floppy_subr.h
Normal file
9
src/include/floppy_subr.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#ifndef FLOPPY_SUBR_H
|
||||
#define FLOPPY_SUBR_H
|
||||
|
||||
int floppy_init(void);
|
||||
int floppy_read(char *dest, unsigned long offset, unsigned long length);
|
||||
void floppy_fini(void);
|
||||
|
||||
|
||||
#endif /* FLOPPY_SUBR_H */
|
15
src/include/northbridge/intel/82860/rdram.h
Normal file
15
src/include/northbridge/intel/82860/rdram.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
void display_rdram_regs(int);
|
||||
void display_spd_dev_row_col_bank(u8*, u8*, u8*);
|
||||
void display_rdram_regs_tparm(int);
|
||||
void display_smbus_spd(void);
|
||||
void display_mch_regs(void);
|
||||
void init_memory(void);
|
||||
|
||||
struct rdram_reg_values {
|
||||
u16 channel_a;
|
||||
u16 channel_b;
|
||||
};
|
||||
|
||||
void rdram_read_reg(u8, u16, u16, struct rdram_reg_values*);
|
||||
|
||||
|
21
src/include/rom/read_bytes.h
Normal file
21
src/include/rom/read_bytes.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
#ifndef ROM_READ_BYTES_H
|
||||
#define ROM_READ_BYTES_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
typedef long byte_offset_t;
|
||||
|
||||
struct stream {
|
||||
int (*init)(void);
|
||||
byte_offset_t (*read)(void *vdest, byte_offset_t count);
|
||||
byte_offset_t (*skip)(byte_offset_t count);
|
||||
void (*fini)(void);
|
||||
};
|
||||
|
||||
#define __stream __attribute__ ((unused,__section__ (".rodata.streams")))
|
||||
|
||||
/* Defined by the linker... */
|
||||
extern struct stream streams[];
|
||||
extern struct stream estreams[];
|
||||
|
||||
#endif /* ROM_READ_BYTES_H */
|
|
@ -13,5 +13,6 @@ object memcmp.o
|
|||
object malloc.o
|
||||
object elfboot.o
|
||||
object do_inflate.o
|
||||
object floppy_subr.o
|
||||
object delay.o
|
||||
object fallback_boot.o USE_FALLBACK_BOOT
|
||||
|
|
|
@ -61,3 +61,10 @@ void mdelay(int msecs)
|
|||
udelay(1000);
|
||||
}
|
||||
}
|
||||
void delay(int secs)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < secs; i++) {
|
||||
mdelay(1000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#include <printk.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
#include <rom/read_bytes.h>
|
||||
#include <subr.h>
|
||||
#include "definitions.h"
|
||||
#include "do_inflate.h"
|
||||
|
@ -24,6 +24,16 @@ static unsigned char window[WSIZE]; /* Sliding window buffer */
|
|||
static unsigned char *window; /* Sliding window buffer */
|
||||
#endif
|
||||
|
||||
static unsigned char get_byte(void)
|
||||
{
|
||||
unsigned char result;
|
||||
if (streams->read(&result, 1) != 1) {
|
||||
printk_err("Unexpected! Out of bytes...\n");
|
||||
while(1) ;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* gzip declarations
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#if USE_ELF_BOOT
|
||||
#include <printk.h>
|
||||
#include <part/fallback_boot.h>
|
||||
#include <boot/elf.h>
|
||||
#include <boot/uniform_boot.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
#include <rom/read_bytes.h>
|
||||
#include <string.h>
|
||||
#include <subr.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
extern unsigned char _text;
|
||||
extern unsigned char _etext;
|
||||
|
@ -60,37 +63,55 @@ int elfboot(size_t totalram)
|
|||
unsigned long offset;
|
||||
Elf_ehdr *ehdr;
|
||||
Elf_phdr *phdr;
|
||||
int header_offset;
|
||||
void *ptr, *entry;
|
||||
int i;
|
||||
|
||||
printk_info("\n");
|
||||
printk_info("Welcome to elfboot, the open sourced starter.\n");
|
||||
printk_info("Febuary 2001, Eric Biederman.\n");
|
||||
printk_info("Version 0.99\n");
|
||||
printk_info("Version 0.9999\n");
|
||||
printk_info("\n");
|
||||
if (streams->init() < 0) {
|
||||
printk_err("Could not initialize driver...\n");
|
||||
goto out;
|
||||
}
|
||||
ptr = get_ube_pointer(totalram);
|
||||
|
||||
post_code(0xf8);
|
||||
/* Read in the initial 512 bytes */
|
||||
for(offset = 0; offset < 512; offset++) {
|
||||
header[offset] = get_byte();
|
||||
}
|
||||
ehdr = (Elf_ehdr *)(&header[0]);
|
||||
entry = (void *)(ehdr->e_entry);
|
||||
|
||||
/* Sanity check the elf header */
|
||||
if ((memcmp(ehdr->e_ident, ELFMAG, 4) != 0) ||
|
||||
(ehdr->e_type != ET_EXEC) ||
|
||||
(!elf_check_arch(ehdr)) ||
|
||||
(ehdr->e_ident[EI_VERSION] != EV_CURRENT) ||
|
||||
(ehdr->e_version != EV_CURRENT) ||
|
||||
(ehdr->e_phoff > ELF_HEAD_SIZE) ||
|
||||
(ehdr->e_phentsize != sizeof(Elf_phdr)) ||
|
||||
((ehdr->e_phoff + (ehdr->e_phentsize * ehdr->e_phnum)) >
|
||||
ELF_HEAD_SIZE)) {
|
||||
/* Read in the initial ELF_HEAD_SIZE bytes */
|
||||
if (streams->read(header, ELF_HEAD_SIZE) != ELF_HEAD_SIZE) {
|
||||
printk_err("Read failed...\n");
|
||||
goto out;
|
||||
}
|
||||
phdr = (Elf_phdr *)&header[ehdr->e_phoff];
|
||||
/* Scan for an elf header */
|
||||
header_offset = -1;
|
||||
for(i = 0; i < ELF_HEAD_SIZE - (sizeof(Elf_ehdr) + sizeof(Elf_phdr)); i+=16) {
|
||||
ehdr = (Elf_ehdr *)(&header[i]);
|
||||
if (memcmp(ehdr->e_ident, ELFMAG, 4) != 0) {
|
||||
continue;
|
||||
}
|
||||
printk_debug("Found ELF candiate at offset %d\n", i);
|
||||
/* Sanity check the elf header */
|
||||
if ((ehdr->e_type == ET_EXEC) &&
|
||||
elf_check_arch(ehdr) &&
|
||||
(ehdr->e_ident[EI_VERSION] == EV_CURRENT) &&
|
||||
(ehdr->e_version == EV_CURRENT) &&
|
||||
(ehdr->e_ehsize == sizeof(Elf_ehdr)) &&
|
||||
(ehdr->e_phentsize = sizeof(Elf_phdr)) &&
|
||||
(ehdr->e_phoff < (ELF_HEAD_SIZE - i)) &&
|
||||
((ehdr->e_phoff + (ehdr->e_phentsize * ehdr->e_phnum)) <=
|
||||
(ELF_HEAD_SIZE - i))) {
|
||||
header_offset = i;
|
||||
break;
|
||||
}
|
||||
ehdr = 0;
|
||||
}
|
||||
if (header_offset == -1) {
|
||||
goto out;
|
||||
}
|
||||
entry = (void *)(ehdr->e_entry);
|
||||
phdr = (Elf_phdr *)&header[ehdr->e_phoff + header_offset];
|
||||
|
||||
/* Sanity check the segments and zero the extra bytes */
|
||||
for(i = 0; i < ehdr->e_phnum; i++) {
|
||||
|
@ -115,7 +136,6 @@ int elfboot(size_t totalram)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
offset = 0;
|
||||
while(1) {
|
||||
|
@ -143,6 +163,7 @@ int elfboot(size_t totalram)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we are out of sections we are done */
|
||||
if (!cur_phdr) {
|
||||
break;
|
||||
|
@ -161,22 +182,23 @@ int elfboot(size_t totalram)
|
|||
start_offset = cur_phdr->p_offset;
|
||||
|
||||
/* Skip intial buffer unused bytes */
|
||||
if (offset < ELF_HEAD_SIZE) {
|
||||
if (start_offset < ELF_HEAD_SIZE) {
|
||||
if (offset < (ELF_HEAD_SIZE - header_offset)) {
|
||||
if (start_offset < (ELF_HEAD_SIZE - header_offset)) {
|
||||
offset = start_offset;
|
||||
} else {
|
||||
offset = ELF_HEAD_SIZE;
|
||||
offset = (ELF_HEAD_SIZE - header_offset);
|
||||
}
|
||||
}
|
||||
|
||||
/* Skip the unused bytes */
|
||||
while(offset < start_offset) {
|
||||
offset++;
|
||||
get_byte();
|
||||
if (streams->skip(start_offset - offset) != (start_offset - offset)) {
|
||||
printk_err("skip failed\n");
|
||||
goto out;
|
||||
}
|
||||
offset = start_offset;
|
||||
|
||||
/* Copy data from the initial buffer */
|
||||
if (offset < ELF_HEAD_SIZE) {
|
||||
if (offset < (ELF_HEAD_SIZE - header_offset)) {
|
||||
size_t len;
|
||||
if ((cur_phdr->p_filesz + start_offset) > ELF_HEAD_SIZE) {
|
||||
len = ELF_HEAD_SIZE - start_offset;
|
||||
|
@ -184,18 +206,24 @@ int elfboot(size_t totalram)
|
|||
else {
|
||||
len = cur_phdr->p_filesz;
|
||||
}
|
||||
memcpy(dest, &header[start_offset], len);
|
||||
memcpy(dest, &header[header_offset + start_offset], len);
|
||||
dest += len;
|
||||
}
|
||||
|
||||
/* Read the section into memory */
|
||||
while(dest < middle) {
|
||||
*(dest++) = get_byte();
|
||||
if (streams->read(dest, middle - dest) != (middle - dest)) {
|
||||
printk_err("Read failed...\n");
|
||||
goto out;
|
||||
}
|
||||
offset += cur_phdr->p_filesz;
|
||||
/* The extra bytes between dest & end have been zeroed */
|
||||
}
|
||||
|
||||
|
||||
/* Reset to booting from this image as late as possible */
|
||||
streams->fini();
|
||||
boot_successful();
|
||||
|
||||
printk_debug("Jumping to boot code\n");
|
||||
post_code(0xfe);
|
||||
|
||||
|
@ -212,6 +240,12 @@ int elfboot(size_t totalram)
|
|||
}
|
||||
printk_err("\n");
|
||||
|
||||
/* Reset to booting from this image as late as possible */
|
||||
streams->fini();
|
||||
#if 0
|
||||
boot_successful();
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* USE_ELF_BOOT */
|
||||
|
|
1038
src/lib/floppy_subr.c
Normal file
1038
src/lib/floppy_subr.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -986,14 +986,6 @@ STATIC int inflate()
|
|||
h = hufts;
|
||||
} while (!e);
|
||||
|
||||
/* Undo too much lookahead. The next read will be byte aligned so we
|
||||
* can discard unused bits in the last meaningful byte.
|
||||
*/
|
||||
while (bk >= 8) {
|
||||
bk -= 8;
|
||||
inptr--;
|
||||
}
|
||||
|
||||
/* flush out slide */
|
||||
flush_output(wp);
|
||||
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
*/
|
||||
|
||||
#include <printk.h>
|
||||
#include <part/fallback_boot.h>
|
||||
#include <params.h>
|
||||
#include <subr.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
#include <rom/read_bytes.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -92,6 +93,7 @@ int linuxbiosmain(unsigned long base, unsigned long totalram)
|
|||
printk_notice("\nnetboot_init test complete, all is well (I hope!)\n");
|
||||
#endif /* USE_TFTP */
|
||||
|
||||
streams->init();
|
||||
printk_debug("Gunzip setup\n");
|
||||
gunzip_setup();
|
||||
printk_debug("Gunzipping boot code\n");
|
||||
|
@ -100,6 +102,7 @@ int linuxbiosmain(unsigned long base, unsigned long totalram)
|
|||
post_code(0xff);
|
||||
return 0;
|
||||
}
|
||||
streams->fini();
|
||||
post_code(0xf8);
|
||||
|
||||
#ifdef TFTP_INITRD
|
||||
|
@ -156,6 +159,8 @@ int linuxbiosmain(unsigned long base, unsigned long totalram)
|
|||
set_display(empty_zero_page, 25, 80);
|
||||
set_initrd(empty_zero_page, initrd_start, initrd_size);
|
||||
|
||||
/* Reset to booting from this image as late as possible */
|
||||
boot_successful();
|
||||
|
||||
printk_debug("Jumping to boot code\n");
|
||||
post_code(0xfe);
|
||||
|
|
|
@ -461,8 +461,20 @@ void compute_allocate_io(struct pci_bus *bus)
|
|||
curbus->number, io_base);
|
||||
}
|
||||
|
||||
/* Walk through all the devices on current bus and oompute IO address space.*/
|
||||
/* Walk through all the devices on current bus and compute IO address space.*/
|
||||
for (curdev = bus->devices; curdev; curdev = curdev->sibling) {
|
||||
u32 class_revision;
|
||||
/* FIXME Special case for VGA for now just note
|
||||
* we have an I/O resource later make certain
|
||||
* we don't have a device conflict.
|
||||
*/
|
||||
pci_read_config_dword(curdev, PCI_CLASS_REVISION, &class_revision);
|
||||
if (((class_revision >> 24) == 0x03) &&
|
||||
((class_revision >> 16) != 0x380)) {
|
||||
printk_debug("Running VGA fix...\n");
|
||||
/* All legacy VGA cards have I/O space registers */
|
||||
curdev->command |= PCI_COMMAND_IO;
|
||||
}
|
||||
for (i = 0; i < 6; i++) {
|
||||
unsigned long size = curdev->size[i];
|
||||
if (size & PCI_BASE_ADDRESS_SPACE_IO) {
|
||||
|
@ -690,8 +702,8 @@ void assign_resources(struct pci_bus *bus)
|
|||
curbus->iobase >> 8);
|
||||
pci_write_config_byte(curbus->self, PCI_IO_LIMIT,
|
||||
curbus->iolimit >> 8);
|
||||
printk_debug("Bus 0x%x iobase to 0x%x iolimit 0x%x\n",
|
||||
bus->number, curbus->iobase, curbus->iolimit);
|
||||
printk_debug("Bus 0x%x Child Bus %x iobase to 0x%x iolimit 0x%x\n",
|
||||
bus->number,curbus->number, curbus->iobase, curbus->iolimit);
|
||||
}
|
||||
|
||||
// set the memory range
|
||||
|
@ -701,8 +713,8 @@ void assign_resources(struct pci_bus *bus)
|
|||
curbus->membase >> 16);
|
||||
pci_write_config_word(curbus->self, PCI_MEMORY_LIMIT,
|
||||
curbus->memlimit >> 16);
|
||||
printk_debug("Bus 0x%x membase to 0x%x memlimit 0x%x\n",
|
||||
bus->number, curbus->membase, curbus->memlimit);
|
||||
printk_debug("Bus 0x%x Child Bus %x membase to 0x%x memlimit 0x%x\n",
|
||||
bus->number,curbus->number, curbus->membase, curbus->memlimit);
|
||||
|
||||
}
|
||||
|
||||
|
@ -713,15 +725,16 @@ void assign_resources(struct pci_bus *bus)
|
|||
curbus->prefmembase >> 16);
|
||||
pci_write_config_word(curbus->self, PCI_PREF_MEMORY_LIMIT,
|
||||
curbus->prefmemlimit >> 16);
|
||||
printk_debug("Bus 0x%x prefmembase to 0x%x prefmemlimit 0x%x\n",
|
||||
bus->number, curbus->prefmembase, curbus->prefmemlimit);
|
||||
printk_debug("Bus 0x%x Child Bus %x prefmembase to 0x%x prefmemlimit 0x%x\n",
|
||||
bus->number,curbus->number, curbus->prefmembase,
|
||||
curbus->prefmemlimit);
|
||||
|
||||
}
|
||||
curbus->self->command |= PCI_COMMAND_MASTER;
|
||||
|
||||
assign_resources(curbus);
|
||||
}
|
||||
|
||||
for (curdev = pci_devices; curdev; curdev = curdev->next) {
|
||||
for (curdev = bus->devices; curdev; curdev = curdev->sibling) {
|
||||
int i;
|
||||
for (i = 0; i < 6; i++) {
|
||||
unsigned long reg;
|
||||
|
|
|
@ -16,6 +16,9 @@ nooption USE_DEFAULT_LAYOUT
|
|||
option STACK_SIZE=0x2000
|
||||
option USE_FALLBACK_BOOT=1
|
||||
|
||||
option USE_RAMTEST=1
|
||||
dir /src/ram
|
||||
|
||||
#/* falback */
|
||||
option ZKERNEL_START=0xffff0000
|
||||
option _ROMBASE= 0xffff8000
|
||||
|
@ -57,7 +60,7 @@ option NO_KEYBOARD
|
|||
option ENABLE_FIXED_AND_VARIABLE_MTRRS
|
||||
#option FINAL_MAINBOARD_FIXUP
|
||||
|
||||
object cacheramtest.o
|
||||
#object cacheramtest.o
|
||||
object mainboard.o
|
||||
object mtrr_values.o
|
||||
object mptable.o HAVE_MP_TABLE
|
||||
|
|
|
@ -8,6 +8,16 @@
|
|||
#include <pc80/isa_dma.h>
|
||||
#include <cpu/i786/multiplier.h>
|
||||
#include <superio/w83627hf.h>
|
||||
#include <superio/generic.h>
|
||||
#include <subr.h>
|
||||
#include <smbus.h>
|
||||
#include <ramtest.h>
|
||||
#include <northbridge/intel/82860/rdram.h>
|
||||
|
||||
|
||||
#define SMBUS_MEM_DEVICE_0 (0xa << 3)
|
||||
extern int rdram_chips; /* number of ram chips on the rimms */
|
||||
|
||||
|
||||
unsigned long initial_apicid[MAX_CPUS] =
|
||||
{
|
||||
|
@ -38,3 +48,92 @@ void hard_reset(void)
|
|||
ich2_hard_reset();
|
||||
}
|
||||
|
||||
static void select_rdram_i2c(void)
|
||||
{
|
||||
unsigned char byte;
|
||||
w83627hf_enter_pnp(SIO_BASE);
|
||||
byte = pnp_read_config(SIO_BASE, 0x2b);
|
||||
byte |= 0x30;
|
||||
pnp_write_config(SIO_BASE, byte, 0x2b);
|
||||
pnp_set_logical_device(SIO_BASE, GPIO_PORT2_DEVICE);
|
||||
pnp_set_enable(SIO_BASE, 1);
|
||||
byte = pnp_read_config(SIO_BASE, 0xf0);
|
||||
byte &= ~(1 << 3);
|
||||
pnp_write_config(SIO_BASE, byte, 0xf0);
|
||||
w83627hf_exit_pnp(SIO_BASE);
|
||||
}
|
||||
|
||||
void cache_ram_start(void)
|
||||
{
|
||||
int error;
|
||||
error = 0;
|
||||
/* displayinit MUST PRECEDE ALL PRINTK! */
|
||||
displayinit();
|
||||
printk_info("printk: Testing %d %s\n", 123, "testing!!!");
|
||||
printk_info("Finding PCI configuration type.\n");
|
||||
pci_set_method();
|
||||
printk_info("Setting up smbus controller\n");
|
||||
smbus_setup();
|
||||
ich2_rtc_init();
|
||||
printk_info("Selecting rdram i2c bus\n");
|
||||
select_rdram_i2c();
|
||||
|
||||
display_smbus_spd();
|
||||
|
||||
init_memory();
|
||||
|
||||
#if 1
|
||||
{
|
||||
unsigned long addr;
|
||||
for(addr = 0; addr < 0x20000000; addr += 0x02000000) {
|
||||
ram_fill(addr, addr + 0x400);
|
||||
}
|
||||
/* Do some dummy writes to flush a write cache, in the
|
||||
* processor.
|
||||
*/
|
||||
ram_fill(0xc0000000, 0xc0000400);
|
||||
for(addr = 0; addr < 0x20000000; addr += 0x02000000) {
|
||||
ram_verify(addr, addr + 0x400, 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
error |= ramcheck(0x00000000, 0x00080000, 20);
|
||||
error |= ramcheck(0x02000000, 0x02080000, 20);
|
||||
error |= ramcheck(0x04000000, 0x04080000, 20);
|
||||
error |= ramcheck(0x06000000, 0x06080000, 20);
|
||||
error |= ramcheck(0x08000000, 0x08080000, 20);
|
||||
error |= ramcheck(0x0a000000, 0x0a080000, 20);
|
||||
error |= ramcheck(0x0c000000, 0x0c080000, 20);
|
||||
|
||||
error |= ramcheck(0x0e000000, 0x0e080000, 20);
|
||||
error |= ramcheck(0x10000000, 0x10080000, 20);
|
||||
error |= ramcheck(0x12000000, 0x12080000, 20);
|
||||
error |= ramcheck(0x14000000, 0x14080000, 20);
|
||||
error |= ramcheck(0x16000000, 0x16080000, 20);
|
||||
error |= ramcheck(0x18000000, 0x18080000, 20);
|
||||
error |= ramcheck(0x1a000000, 0x1a080000, 20);
|
||||
error |= ramcheck(0x1c000000, 0x1c080000, 20);
|
||||
error |= ramcheck(0x1e000000, 0x1e080000, 20);
|
||||
#if 0
|
||||
error |= ramcheck(0x00000000, 0x00080000, 20);
|
||||
#endif
|
||||
#if 1
|
||||
display_rdram_regs(rdram_chips );
|
||||
#endif
|
||||
#if 1
|
||||
display_mch_regs();
|
||||
#endif
|
||||
if (error) {
|
||||
printk_err("Something isn't working!!!\n");
|
||||
while(1);
|
||||
} else {
|
||||
printk_info("Leaving cacheram...\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -55,6 +55,34 @@ void smp_write_config_table(void *v, unsigned long * processor_map)
|
|||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
|
||||
0x04, (4 <<2)|0, 0x02, 0x10);
|
||||
|
||||
/* Four standard PCI slots */
|
||||
/* Slot 1 */
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
|
||||
0x04, (7 <<2)|0, 0x02, 0x10);
|
||||
/* Slot 2 */
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
|
||||
0x04, (1 <<2)|0, 0x02, 0x11);
|
||||
/* Slot 3 */
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
|
||||
0x04, (2 <<2)|0, 0x02, 0x12);
|
||||
/* Slot 4 */
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
|
||||
0x04, (3 <<2)|0, 0x02, 0x13);
|
||||
|
||||
/* Two 64 bit PCI slots */
|
||||
/* Slot 1 */
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
|
||||
0x03, (1 <<2)|0, 0x02, 0x12);
|
||||
/* Slot 2 */
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
|
||||
0x03, (2 <<2)|0, 0x02, 0x12);
|
||||
|
||||
/* Two SCSI */
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
|
||||
0x03, (4 <<2)|0, 0x02, 0x12);
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_LEVEL|MP_IRQ_POLARITY_LOW,
|
||||
0x03, (4 <<2)|1, 0x02, 0x12);
|
||||
|
||||
/* ISA backward compatibility interrupts */
|
||||
smp_write_intsrc(mc, mp_ExtINT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
|
||||
0x05, 0x00, 0x02, 0x00);
|
||||
|
@ -66,6 +94,8 @@ void smp_write_config_table(void *v, unsigned long * processor_map)
|
|||
0x05, 0x03, 0x02, 0x03);
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
|
||||
0x05, 0x04, 0x02, 0x04);
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
|
||||
0x05, 0x05, 0x02, 0x05);
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
|
||||
0x05, 0x06, 0x02, 0x06);
|
||||
smp_write_intsrc(mc, mp_INT, MP_IRQ_TRIGGER_DEFAULT|MP_IRQ_POLARITY_DEFAULT,
|
||||
|
|
|
@ -2,3 +2,5 @@ mainboardinit arch/i386/lib/set_memory_size_noop.inc
|
|||
mainboardinit arch/i386/lib/cpu_reset.inc
|
||||
|
||||
object northbridge.o
|
||||
object rdram_setup.o
|
||||
object rdram_debug.o
|
||||
|
|
301
src/northbridge/intel/82860/rdram_debug.c
Normal file
301
src/northbridge/intel/82860/rdram_debug.c
Normal file
|
@ -0,0 +1,301 @@
|
|||
#include <printk.h>
|
||||
#include <stdarg.h>
|
||||
#include <types.h>
|
||||
#include <string.h>
|
||||
#include <subr.h>
|
||||
#include <serial_subr.h>
|
||||
#include <pci.h>
|
||||
#include <arch/io.h>
|
||||
#include <cpu/p6/msr.h>
|
||||
#include <cpu/p6/mtrr.h>
|
||||
#include <arch/cache_ram.h>
|
||||
#include <smbus.h>
|
||||
#include <ramtest.h>
|
||||
#include <southbridge/intel/82801.h>
|
||||
#include <superio/generic.h>
|
||||
#include <superio/w83627hf.h>
|
||||
#include <northbridge/intel/82860/rdram.h>
|
||||
|
||||
#define LPC_BUS 0
|
||||
#define LPC_DEVFN ((0x1f << 3) + 0)
|
||||
|
||||
#define ICH2HUB_BUS 0
|
||||
#define ICH2HUB_DEVFN ((0x1e << 3) + 0)
|
||||
|
||||
#define I860MCH_BUS 0
|
||||
#define I860MCH_DEVFN ((0x00 << 3) + 0)
|
||||
|
||||
#define I860HUBA_BUS 0
|
||||
#define I860HUBA_DEVFN ((0x01 << 3) + 0)
|
||||
|
||||
#define I860HUBB_BUS 0
|
||||
#define I860HUBB_DEVFN ((0x02 << 3) + 0)
|
||||
|
||||
#define SMBUS_MEM_DEVICE_0 (0xa << 3)
|
||||
|
||||
#define TSCYCLE_SLOW 1000 /* ns */
|
||||
#define TSCYCLE_FAST 10 /* ns */
|
||||
|
||||
#define I860_MCH_BUS 0
|
||||
#define I860_MCH_DEVFN 0
|
||||
|
||||
#define MCH_GAR0 0x40
|
||||
#define MCH_GAR1 0x41
|
||||
#define MCH_GAR2 0x42
|
||||
#define MCH_GAR3 0x43
|
||||
#define MCH_GAR4 0x44
|
||||
#define MCH_GAR5 0x45
|
||||
#define MCH_GAR6 0x46
|
||||
#define MCH_GAR7 0x47
|
||||
#define MCH_GAR8 0x48
|
||||
#define MCH_GAR9 0x49
|
||||
#define MCH_GAR10 0x4a
|
||||
#define MCH_GAR11 0x4b
|
||||
#define MCH_GAR12 0x4c
|
||||
#define MCH_GAR13 0x4d
|
||||
#define MCH_GAR14 0x4e
|
||||
#define MCH_GAR15 0x4f
|
||||
#define MCH_MCHCFG 0x50
|
||||
#define MCH_FDHC 0x58
|
||||
#define MCH_PAM0 0x59
|
||||
#define MCH_PAM1 0x5a
|
||||
#define MCH_PAM2 0x5b
|
||||
#define MCH_PAM3 0x5c
|
||||
#define MCH_PAM4 0x5d
|
||||
#define MCH_PAM5 0x5e
|
||||
#define MCH_PAM6 0x5f
|
||||
#define MCH_GBA0 0x60
|
||||
#define MCH_GBA1 0x62
|
||||
#define MCH_GBA2 0x64
|
||||
#define MCH_GBA3 0x66
|
||||
#define MCH_GBA4 0x68
|
||||
#define MCH_GBA5 0x6a
|
||||
#define MCH_GBA6 0x6c
|
||||
#define MCH_GBA7 0x6e
|
||||
#define MCH_GBA8 0x70
|
||||
#define MCH_GBA9 0x72
|
||||
#define MCH_GBA10 0x74
|
||||
#define MCH_GBA11 0x76
|
||||
#define MCH_GBA12 0x78
|
||||
#define MCH_GBA13 0x7a
|
||||
#define MCH_GBA14 0x7c
|
||||
#define MCH_GBA15 0x7e
|
||||
#define MCH_RDPS 0x88
|
||||
#define MCH_DRD 0x90
|
||||
#define MCH_RICM 0x94
|
||||
#define MCH_SMRAM 0x9d
|
||||
#define MCH_ESMRAM 0x9e
|
||||
#define MCH_RDT 0xbe
|
||||
#define MCH_TOM 0xc4
|
||||
#define MCH_ERRSTS 0xc8
|
||||
#define MCH_ERRCMD 0xca
|
||||
#define MCH_SMICMD 0xcc
|
||||
#define MCH_SCICMD 0xce
|
||||
#define MCH_DRAMRC 0xdc
|
||||
#define MCH_DERRCTL 0xe2
|
||||
#define MCH_EAP 0xe4
|
||||
|
||||
#define RICM_BUSY (1 << 23)
|
||||
#define RICM_DONE (1 << 27)
|
||||
|
||||
|
||||
#define __S(NAME) NAME##_SHIFT
|
||||
#define __B(NAME) NAME##_BITS
|
||||
#define __BIT_MASK(SHIFT, BITS) ((1 << (BITS + SHIFT)) - (1 << (SHIFT)))
|
||||
#define MASK(NAME) __BIT_MASK(__S(NAME), __B(NAME))
|
||||
#define NVAL(NAME, VAL) (MASK(NAME) & ((VAL) << __S(NAME)))
|
||||
#define VAL(NAME, VALUE) ((MASK(NAME) & VALUE) >> __S(NAME))
|
||||
|
||||
#define RICM_CMD_SHIFT 0
|
||||
#define RICM_CMD_BITS 5
|
||||
#define RICM_ADDR_SHIFT 5
|
||||
#define RICM_ADDR_BITS 5
|
||||
#define RICM_REG_SHIFT 10
|
||||
#define RICM_REG_BITS 9
|
||||
#define RICM_BROADCAST_SHIFT 19
|
||||
#define RICM_BROADCAST_BITS 1
|
||||
#define RICM_CHANNEL_SHIFT 20
|
||||
#define RICM_CHANNEL_BITS 2
|
||||
|
||||
#define CMD_RDRAM_READ_REG 0
|
||||
#define CMD_RDRAM_WRITE_REG 1
|
||||
#define CMD_RDRAM_SET_RESET 2
|
||||
#define CMD_SET_FAST_CLK 4
|
||||
#define CMD_TEMP_CALIBRATE_ENABLE 5
|
||||
#define CMD_TEMP_CALIBRATE 6
|
||||
#define CMD_MRH_REDIRECT_NEXT_SIO 8
|
||||
#define CMD_MRH_STICK_SIO_RESET 9
|
||||
#define CMD_RDRAM_CLEAR_RESET 11
|
||||
#define CMD_RDRAM_CURRENT_CALIBRATION 16
|
||||
#define CMD_RDRAM_SIO_RESET 17
|
||||
#define CMD_RDRAM_POWERDOWN_EXIT 18
|
||||
#define CMD_RDRAM_POWERDOWN_ENTRY 19
|
||||
#define CMD_RDRAM_NAP_ENTRY 20
|
||||
#define CMD_RDRAM_NAP_EXIT 21
|
||||
#define CMD_RDRAM_REFRESH 22
|
||||
#define CMD_RDRAM_PRECHARGE 23
|
||||
#define CMD_MANUAL_CURRENT_CALIBRATION 24
|
||||
#define CMD_MCH_RAC_LOAD_RACA_CONFIG 25
|
||||
#define CMD_MCH_RAC_LOAD_RACB_CONFIG 26
|
||||
#define CMD_MCH_INITIALIZE_RAC 27
|
||||
#define CMD_MCH_RAC_CURRENT_CALIBRATION 28
|
||||
#define CMD_MCH_RAC_TEMP_CALIBRATE 29
|
||||
#define CMD_POWERUP_ALL_SEQUENCE 31
|
||||
|
||||
#define REG_INIT 0x21
|
||||
#define REG_TEST34 0x22
|
||||
#define REG_CNFGA 0x23
|
||||
#define REG_CNFGB 0x24
|
||||
#define REG_DEVID 0x40
|
||||
#define REG_REFB 0x41
|
||||
#define REG_REFR 0x42
|
||||
#define REG_CCA 0x43
|
||||
#define REG_CCB 0x44
|
||||
#define REG_NAPX 0x45
|
||||
#define REG_PDNXA 0x46
|
||||
#define REG_PDNX 0x47
|
||||
#define REG_TPARM 0x48
|
||||
#define REG_TFRM 0x49
|
||||
#define REG_TCDLY1 0x4a
|
||||
#define REG_SKIP 0x4b
|
||||
#define REG_TCYCLE 0x4c
|
||||
#define REG_TEST77 0x4d
|
||||
#define REG_TEST78 0x4e
|
||||
#define REG_TEST79 0x4f
|
||||
|
||||
#define BCAST 0xffff
|
||||
|
||||
//int rdram_chips=0; /* number of ram chips on the rimms */
|
||||
//static u32 total_rdram; /* Total rdram found */
|
||||
|
||||
u16 rdram_regs[] = {
|
||||
REG_INIT,
|
||||
REG_TEST34,
|
||||
REG_CNFGA,
|
||||
REG_CNFGB,
|
||||
REG_DEVID,
|
||||
REG_REFB,
|
||||
REG_REFR,
|
||||
REG_CCA,
|
||||
REG_CCB,
|
||||
REG_NAPX,
|
||||
REG_PDNXA,
|
||||
REG_PDNX,
|
||||
REG_TPARM,
|
||||
REG_TFRM,
|
||||
REG_TCDLY1,
|
||||
REG_SKIP,
|
||||
REG_TCYCLE,
|
||||
REG_TEST77,
|
||||
REG_TEST78,
|
||||
REG_TEST79,
|
||||
};
|
||||
char *rdram_reg_names[] = {
|
||||
"INIT",
|
||||
"TEST34",
|
||||
"CNFGA",
|
||||
"CNFGB",
|
||||
"DEVID",
|
||||
"REFB",
|
||||
"REFR",
|
||||
"CCA",
|
||||
"CCB",
|
||||
"NAPX",
|
||||
"PDNXA",
|
||||
"PDNX",
|
||||
"TPARM",
|
||||
"TFRM",
|
||||
"TCDLY1",
|
||||
"SKIP",
|
||||
"TCYCLE",
|
||||
"TEST77",
|
||||
"TEST78",
|
||||
"TEST79",
|
||||
};
|
||||
|
||||
|
||||
void display_spd_dev_row_col_bank(u8 *spd_devices, u8 *spd_row_col, u8 *spd_banks)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i=0;i<4;i++)
|
||||
printk_debug("Devices %d, Row Bits %d, Col Bits %d, Bank Bits %d\n",
|
||||
spd_devices[i],(spd_row_col[i]>>4),(spd_row_col[i]&0x0f),spd_banks[i]);
|
||||
|
||||
}
|
||||
|
||||
void display_rdram_regs_tparm(int rdram_chips)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
for(i = 0; i < rdram_chips; i++) {
|
||||
for(j = 12; j < 15; j+=2) {
|
||||
struct rdram_reg_values values;
|
||||
u16 reg = rdram_regs[j];
|
||||
rdram_read_reg(0, i, reg, &values);
|
||||
printk_debug("rdram: %2d reg: %02x %10s a: 0x%04x b: 0x%04x\n",
|
||||
i, reg, rdram_reg_names[j], values.channel_a, values.channel_b); }
|
||||
}
|
||||
}
|
||||
|
||||
void display_rdram_regs(int rdram_chips )
|
||||
{
|
||||
int i,j;
|
||||
|
||||
for(i = 0; i < rdram_chips; i++) {
|
||||
for(j = 0; j < sizeof(rdram_regs)/sizeof(rdram_regs[0]); j++) {
|
||||
struct rdram_reg_values values;
|
||||
u16 reg = rdram_regs[j];
|
||||
rdram_read_reg(0, i, reg, &values);
|
||||
printk_debug("rdram: %2d reg: %02x %10s a: 0x%04x b: 0x%04x\n",
|
||||
i, reg, rdram_reg_names[j], values.channel_a, values.channel_b);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void display_smbus_spd(void)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
for(j = SMBUS_MEM_DEVICE_0; j < SMBUS_MEM_DEVICE_0 + 4; j++) {
|
||||
int status = 0;
|
||||
if ((j == 0x1b) || 0) {
|
||||
printk_debug("skipping device: %02x\n", j);
|
||||
continue;
|
||||
}
|
||||
printk_debug("smbus_device: %02x\n", j);
|
||||
for(i = 0; (i < 128) && (status == 0); i++) {
|
||||
unsigned char byte;
|
||||
status = smbus_read_byte(j, i, &byte);
|
||||
if (status != 0) {
|
||||
printk_debug("bad device\n");
|
||||
continue;
|
||||
}
|
||||
printk_debug("0x%02x ", byte);
|
||||
if ((i &0x0f) == 0x0f) {
|
||||
printk_debug("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
printk_debug("\n");
|
||||
}
|
||||
|
||||
void display_mch_regs(void)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
printk_debug("MCH Register Dump\n");
|
||||
for(i = 0; i < 16; i++) {
|
||||
printk_debug("%02x: ", i << 4);
|
||||
for(j = 0; j < 16; j++) {
|
||||
u8 byte;
|
||||
u8 addr = (i << 4) | j;
|
||||
pcibios_read_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, addr, &byte);
|
||||
printk_debug("%02x ", byte);
|
||||
}
|
||||
printk_debug("\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
866
src/northbridge/intel/82860/rdram_setup.c
Normal file
866
src/northbridge/intel/82860/rdram_setup.c
Normal file
|
@ -0,0 +1,866 @@
|
|||
#include <printk.h>
|
||||
#include <stdarg.h>
|
||||
#include <types.h>
|
||||
#include <string.h>
|
||||
#include <subr.h>
|
||||
#include <serial_subr.h>
|
||||
#include <pci.h>
|
||||
#include <arch/io.h>
|
||||
#include <cpu/p6/msr.h>
|
||||
#include <cpu/p6/mtrr.h>
|
||||
#include <arch/cache_ram.h>
|
||||
#include <smbus.h>
|
||||
#include <ramtest.h>
|
||||
#include <southbridge/intel/82801.h>
|
||||
#include <superio/generic.h>
|
||||
#include <superio/w83627hf.h>
|
||||
#include <northbridge/intel/82860/rdram.h>
|
||||
|
||||
#define LPC_BUS 0
|
||||
#define LPC_DEVFN ((0x1f << 3) + 0)
|
||||
|
||||
#define ICH2HUB_BUS 0
|
||||
#define ICH2HUB_DEVFN ((0x1e << 3) + 0)
|
||||
|
||||
#define I860MCH_BUS 0
|
||||
#define I860MCH_DEVFN ((0x00 << 3) + 0)
|
||||
|
||||
#define I860HUBA_BUS 0
|
||||
#define I860HUBA_DEVFN ((0x01 << 3) + 0)
|
||||
|
||||
#define I860HUBB_BUS 0
|
||||
#define I860HUBB_DEVFN ((0x02 << 3) + 0)
|
||||
|
||||
#define SMBUS_MEM_DEVICE_0 (0xa << 3)
|
||||
|
||||
#define TSCYCLE_SLOW 1000 /* ns */
|
||||
#define TSCYCLE_FAST 10 /* ns */
|
||||
void ndelay(unsigned long);
|
||||
|
||||
#define I860_MCH_BUS 0
|
||||
#define I860_MCH_DEVFN 0
|
||||
|
||||
#define MCH_GAR0 0x40
|
||||
#define MCH_GAR1 0x41
|
||||
#define MCH_GAR2 0x42
|
||||
#define MCH_GAR3 0x43
|
||||
#define MCH_GAR4 0x44
|
||||
#define MCH_GAR5 0x45
|
||||
#define MCH_GAR6 0x46
|
||||
#define MCH_GAR7 0x47
|
||||
#define MCH_GAR8 0x48
|
||||
#define MCH_GAR9 0x49
|
||||
#define MCH_GAR10 0x4a
|
||||
#define MCH_GAR11 0x4b
|
||||
#define MCH_GAR12 0x4c
|
||||
#define MCH_GAR13 0x4d
|
||||
#define MCH_GAR14 0x4e
|
||||
#define MCH_GAR15 0x4f
|
||||
#define MCH_MCHCFG 0x50
|
||||
#define MCH_FDHC 0x58
|
||||
#define MCH_PAM0 0x59
|
||||
#define MCH_PAM1 0x5a
|
||||
#define MCH_PAM2 0x5b
|
||||
#define MCH_PAM3 0x5c
|
||||
#define MCH_PAM4 0x5d
|
||||
#define MCH_PAM5 0x5e
|
||||
#define MCH_PAM6 0x5f
|
||||
#define MCH_GBA0 0x60
|
||||
#define MCH_GBA1 0x62
|
||||
#define MCH_GBA2 0x64
|
||||
#define MCH_GBA3 0x66
|
||||
#define MCH_GBA4 0x68
|
||||
#define MCH_GBA5 0x6a
|
||||
#define MCH_GBA6 0x6c
|
||||
#define MCH_GBA7 0x6e
|
||||
#define MCH_GBA8 0x70
|
||||
#define MCH_GBA9 0x72
|
||||
#define MCH_GBA10 0x74
|
||||
#define MCH_GBA11 0x76
|
||||
#define MCH_GBA12 0x78
|
||||
#define MCH_GBA13 0x7a
|
||||
#define MCH_GBA14 0x7c
|
||||
#define MCH_GBA15 0x7e
|
||||
#define MCH_RDPS 0x88
|
||||
#define MCH_DRD 0x90
|
||||
#define MCH_RICM 0x94
|
||||
#define MCH_SMRAM 0x9d
|
||||
#define MCH_ESMRAM 0x9e
|
||||
#define MCH_RDT 0xbe
|
||||
#define MCH_TOM 0xc4
|
||||
#define MCH_ERRSTS 0xc8
|
||||
#define MCH_ERRCMD 0xca
|
||||
#define MCH_SMICMD 0xcc
|
||||
#define MCH_SCICMD 0xce
|
||||
#define MCH_DRAMRC 0xdc
|
||||
#define MCH_DERRCTL 0xe2
|
||||
#define MCH_EAP 0xe4
|
||||
|
||||
#define RICM_BUSY (1 << 23)
|
||||
#define RICM_DONE (1 << 27)
|
||||
|
||||
|
||||
#define __S(NAME) NAME##_SHIFT
|
||||
#define __B(NAME) NAME##_BITS
|
||||
#define __BIT_MASK(SHIFT, BITS) ((1 << (BITS + SHIFT)) - (1 << (SHIFT)))
|
||||
#define MASK(NAME) __BIT_MASK(__S(NAME), __B(NAME))
|
||||
#define NVAL(NAME, VAL) (MASK(NAME) & ((VAL) << __S(NAME)))
|
||||
#define VAL(NAME, VALUE) ((MASK(NAME) & VALUE) >> __S(NAME))
|
||||
|
||||
#define RICM_CMD_SHIFT 0
|
||||
#define RICM_CMD_BITS 5
|
||||
#define RICM_ADDR_SHIFT 5
|
||||
#define RICM_ADDR_BITS 5
|
||||
#define RICM_REG_SHIFT 10
|
||||
#define RICM_REG_BITS 9
|
||||
#define RICM_BROADCAST_SHIFT 19
|
||||
#define RICM_BROADCAST_BITS 1
|
||||
#define RICM_CHANNEL_SHIFT 20
|
||||
#define RICM_CHANNEL_BITS 2
|
||||
|
||||
#define CMD_RDRAM_READ_REG 0
|
||||
#define CMD_RDRAM_WRITE_REG 1
|
||||
#define CMD_RDRAM_SET_RESET 2
|
||||
#define CMD_SET_FAST_CLK 4
|
||||
#define CMD_TEMP_CALIBRATE_ENABLE 5
|
||||
#define CMD_TEMP_CALIBRATE 6
|
||||
#define CMD_MRH_REDIRECT_NEXT_SIO 8
|
||||
#define CMD_MRH_STICK_SIO_RESET 9
|
||||
#define CMD_RDRAM_CLEAR_RESET 11
|
||||
#define CMD_RDRAM_CURRENT_CALIBRATION 16
|
||||
#define CMD_RDRAM_SIO_RESET 17
|
||||
#define CMD_RDRAM_POWERDOWN_EXIT 18
|
||||
#define CMD_RDRAM_POWERDOWN_ENTRY 19
|
||||
#define CMD_RDRAM_NAP_ENTRY 20
|
||||
#define CMD_RDRAM_NAP_EXIT 21
|
||||
#define CMD_RDRAM_REFRESH 22
|
||||
#define CMD_RDRAM_PRECHARGE 23
|
||||
#define CMD_MANUAL_CURRENT_CALIBRATION 24
|
||||
#define CMD_MCH_RAC_LOAD_RACA_CONFIG 25
|
||||
#define CMD_MCH_RAC_LOAD_RACB_CONFIG 26
|
||||
#define CMD_MCH_INITIALIZE_RAC 27
|
||||
#define CMD_MCH_RAC_CURRENT_CALIBRATION 28
|
||||
#define CMD_MCH_RAC_TEMP_CALIBRATE 29
|
||||
#define CMD_POWERUP_ALL_SEQUENCE 31
|
||||
|
||||
#define REG_INIT 0x21
|
||||
#define REG_TEST34 0x22
|
||||
#define REG_CNFGA 0x23
|
||||
#define REG_CNFGB 0x24
|
||||
#define REG_DEVID 0x40
|
||||
#define REG_REFB 0x41
|
||||
#define REG_REFR 0x42
|
||||
#define REG_CCA 0x43
|
||||
#define REG_CCB 0x44
|
||||
#define REG_NAPX 0x45
|
||||
#define REG_PDNXA 0x46
|
||||
#define REG_PDNX 0x47
|
||||
#define REG_TPARM 0x48
|
||||
#define REG_TFRM 0x49
|
||||
#define REG_TCDLY1 0x4a
|
||||
#define REG_SKIP 0x4b
|
||||
#define REG_TCYCLE 0x4c
|
||||
#define REG_TEST77 0x4d
|
||||
#define REG_TEST78 0x4e
|
||||
#define REG_TEST79 0x4f
|
||||
|
||||
#define BCAST 0xffff
|
||||
|
||||
static void rdram_wait_until_ready(void)
|
||||
{
|
||||
u32 ricm;
|
||||
do {
|
||||
pcibios_read_config_dword(I860_MCH_BUS, I860_MCH_DEVFN, MCH_RICM, &ricm);
|
||||
} while(ricm & RICM_BUSY);
|
||||
ndelay(1000); /* delay after ready because the documentation says to */
|
||||
}
|
||||
|
||||
/* rdram timing tables */
|
||||
static u16 tparm[5]={0x3a,0x3a,0x3a,0x4a,0x5a};
|
||||
static u16 tcdly1[5]={0,1,2,2,2};
|
||||
|
||||
/* serial presence detect needed variables */
|
||||
/* Byte 99 number of devices for each stick */
|
||||
static u8 spd_devices[4]={0,0,0,0};
|
||||
/* Byte 4 # of row address bits, # of column address bits */
|
||||
static u8 spd_row_col[4]={0,0,0,0};
|
||||
/* Byte 5 # of bank bits lower nibble */
|
||||
static u8 spd_banks[4]={0,0,0,0};
|
||||
/* Byte 9 Misc. Device configuration S28, and S3 bits are used */
|
||||
static u8 spd_misc_conf[4]={0,0,0,0};
|
||||
/* Byte 31 power down exit max time phase A (tPDNXA,max) */
|
||||
static u8 spd_pdnxa_max[4]={0,0,0,0};
|
||||
/* Byte 32 power down exit max time phase B (tPDNXB,max) */
|
||||
static u8 spd_pdnxb_max[4]={0,0,0,0};
|
||||
/* Byte 33 Map exit max time phase A (tNAPXA,max) */
|
||||
static u8 spd_napxa_max[4]={0,0,0,0};
|
||||
/* Byte 34 Nap exit max time phase B (tNAPXB,max) */
|
||||
static u8 spd_napxb_max[4]={0,0,0,0};
|
||||
/* Byte 12 Min ras to cas cycles */
|
||||
static u8 spd_rcd_min[4]={0,0,0,0};
|
||||
/* Byte 100 Module data width */
|
||||
static u8 spd_data_width[4]={0,0,0,0};
|
||||
/* Byte 35 bits 0-3<<8 + byte 37 give the rdram max mhz rate */
|
||||
static u16 spd_mhz_max[4]={0,0,0,0};
|
||||
/* Byte 35 bits 4-7<<4 + byte 36 give the rdram min mhz rate */
|
||||
static u16 spd_mhz_min[4]={0,0,0,0};
|
||||
/* The size of each device in mega bytes. */
|
||||
static u8 spd_size[2]={0,0};
|
||||
|
||||
int rdram_chips=0; /* number of ram chips on the rimms */
|
||||
static u32 total_rdram; /* Total rdram found */
|
||||
|
||||
/* register index tables */
|
||||
static u8 mch_gar[16] ={MCH_GAR0,MCH_GAR1,MCH_GAR2,MCH_GAR3,MCH_GAR4,MCH_GAR5,
|
||||
MCH_GAR6,MCH_GAR7,MCH_GAR8,MCH_GAR9,MCH_GAR10,MCH_GAR11,
|
||||
MCH_GAR12,MCH_GAR13,MCH_GAR14,MCH_GAR15};
|
||||
|
||||
static u8 mch_gba[16] ={MCH_GBA0,MCH_GBA1,MCH_GBA2,MCH_GBA3,MCH_GBA4,MCH_GBA5,
|
||||
MCH_GBA6,MCH_GBA7,MCH_GBA8,MCH_GBA9,MCH_GBA10,MCH_GBA11,
|
||||
MCH_GBA12,MCH_GBA13,MCH_GBA14,MCH_GBA15};
|
||||
|
||||
static void __rdram_run_command(u8 channel, u16 sdevice_id, u16 reg, u16 command)
|
||||
{
|
||||
u32 ricm;
|
||||
int broadcast;
|
||||
|
||||
broadcast = 0;
|
||||
if (sdevice_id == BCAST) {
|
||||
broadcast = 1;
|
||||
sdevice_id = 0;
|
||||
}
|
||||
|
||||
/* Read the old register value and modify it */
|
||||
pcibios_read_config_dword(I860_MCH_BUS, I860_MCH_DEVFN, MCH_RICM, &ricm);
|
||||
ricm &= ~(MASK(RICM_CHANNEL) | MASK(RICM_BROADCAST) | MASK(RICM_ADDR) |
|
||||
MASK(RICM_REG) | MASK(RICM_CMD));
|
||||
ricm |= NVAL(RICM_CHANNEL, channel);
|
||||
ricm |= NVAL(RICM_BROADCAST, broadcast);
|
||||
ricm |= NVAL(RICM_ADDR, sdevice_id);
|
||||
ricm |= NVAL(RICM_REG, reg);
|
||||
ricm |= NVAL(RICM_CMD, command);
|
||||
|
||||
/* Write the command */
|
||||
pcibios_write_config_dword(I860_MCH_BUS, I860_MCH_DEVFN, MCH_RICM, ricm);
|
||||
|
||||
/* Start the command running */
|
||||
ricm |= RICM_BUSY;
|
||||
pcibios_write_config_dword(I860_MCH_BUS, I860_MCH_DEVFN, MCH_RICM, ricm);
|
||||
|
||||
/* Wait until the command completes */
|
||||
rdram_wait_until_ready();
|
||||
}
|
||||
|
||||
static void rdram_run_command(u8 channel, u16 sdevice_id, u16 command)
|
||||
{
|
||||
/* Wait until the previous cmd completes */
|
||||
rdram_wait_until_ready();
|
||||
|
||||
/* Run the command */
|
||||
__rdram_run_command(channel, sdevice_id, 0, command);
|
||||
}
|
||||
|
||||
void rdram_read_reg(u8 channel, u16 sdevice_id, u16 reg, struct rdram_reg_values *res)
|
||||
{
|
||||
u32 drd;
|
||||
|
||||
/* Wait until the previous cmd completes */
|
||||
rdram_wait_until_ready();
|
||||
|
||||
__rdram_run_command(channel, sdevice_id, reg, CMD_RDRAM_READ_REG);
|
||||
|
||||
/* Read back the register value */
|
||||
pcibios_read_config_dword(I860_MCH_BUS, I860_MCH_DEVFN, MCH_DRD, &drd);
|
||||
|
||||
res->channel_a = (drd >> 16) &0xffff;
|
||||
res->channel_b = drd & 0xffff;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
static void rdram_write_reg(u8 channel, u16 sdevice_id, u16 reg,
|
||||
u16 channel_a, u16 channel_b)
|
||||
{
|
||||
u32 drd;
|
||||
|
||||
/* Wait until the previous cmd completes */
|
||||
rdram_wait_until_ready();
|
||||
|
||||
|
||||
/* Write the data values */
|
||||
drd = (((u32)channel_a) << 16) | channel_b;
|
||||
pcibios_write_config_dword(I860_MCH_BUS, I860_MCH_DEVFN, MCH_DRD, drd);
|
||||
|
||||
__rdram_run_command(channel, sdevice_id, reg, CMD_RDRAM_WRITE_REG);
|
||||
|
||||
/* Wait until the command completes */
|
||||
rdram_wait_until_ready();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void set_sdevid(int rdram_devices)
|
||||
{
|
||||
int i;
|
||||
/* First disable the repeater and set every RDRAM to the
|
||||
* maximum address I can address
|
||||
*/
|
||||
rdram_write_reg(0, BCAST, REG_INIT, 0x1f, 0x1f);
|
||||
for(i = 0; i < rdram_devices; i++) {
|
||||
/* Set SDEVID and reenable the repeater */
|
||||
rdram_write_reg(0, 0x1f, REG_INIT,
|
||||
(1 << 7) | (i & 0x1f), (1 << 7) | (i & 0x1f));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void set_devid(int rdram_devices)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < rdram_devices; i++) {
|
||||
/* FIXME make this smarter */
|
||||
/* Initially set DEVID == SDEVID */
|
||||
if ((i % 4) != 5) {
|
||||
rdram_write_reg(0, i, REG_DEVID, i, i );
|
||||
} else {
|
||||
rdram_write_reg(0, i, REG_DEVID, 0x1f, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void set_init_bits(int rdram_devices)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < rdram_devices; i++) {
|
||||
/* Now that the chip is up and running setup the
|
||||
* power management modes.
|
||||
*/
|
||||
rdram_write_reg(0, i, REG_INIT,
|
||||
(1 << 9) | (1 << 7) | (1 << 6) | (i & 0x1f),
|
||||
(1 << 9) | (1 << 7) | (1 << 6) | (i & 0x1f)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
static void rdram_read_domain_initialization(int rdram_devices)
|
||||
{
|
||||
u8 rdt=0x8d;
|
||||
int i,j,k;
|
||||
u32 data;
|
||||
u32 *mem;
|
||||
u8 adj_a[32],adj_b[32];
|
||||
u8 l=20;
|
||||
|
||||
total_rdram=0;
|
||||
if((spd_rcd_min[0]==8)||(spd_rcd_min[1]==8))
|
||||
rdt=0x4d;
|
||||
/* Set all the rdram devices to the fastest clock cycles */
|
||||
rdram_write_reg(0, BCAST, REG_TCDLY1, 0, 0 );
|
||||
rdram_write_reg(0, BCAST, REG_TPARM, 0x3a, 0x3a);
|
||||
|
||||
/* find the slowest RDT timming */
|
||||
pcibios_write_config_byte(I860_MCH_BUS,I860_MCH_DEVFN,MCH_RDT,rdt);
|
||||
mem=RAM_ADDR(0x100000);
|
||||
for(j=0;j<rdram_devices;j++) {
|
||||
for(k=0,i=4,data=0x00000001;k< ((2048/4)+4);k++,i++,data+=0x00000001) {
|
||||
if(i>7) {
|
||||
data-=00000004;
|
||||
i=0;
|
||||
}
|
||||
mem[k]=data;
|
||||
}
|
||||
printk_debug("Device = %d, %x, %x\n",j,mem[0],mem[4]);
|
||||
adj_a[j]=(mem[0]&0x0ff)-1;
|
||||
adj_b[j]=(mem[4]&0x0ff)-1;
|
||||
if(adj_a[j]<l) l=adj_a[j];
|
||||
if(adj_b[j]<l) l=adj_b[j];
|
||||
if(j<spd_devices[0]) {
|
||||
if(spd_size[0]==32)
|
||||
mem+=0x1000000; /* add 64 meg */
|
||||
else
|
||||
mem+=0x0800000; /* add 32 meg */
|
||||
}
|
||||
else {
|
||||
if(spd_size[1]==32)
|
||||
mem+=0x1000000; /* add 64 meg */
|
||||
else
|
||||
mem+=0x0800000; /* add 32 meg */
|
||||
}
|
||||
}
|
||||
rdt-=l;
|
||||
printk_debug("RDT = %x, Lowest Offset = %d\n",rdt,l);
|
||||
for(i=0;i<rdram_devices;i++) {
|
||||
adj_a[i]-=l;
|
||||
adj_b[i]-=l;
|
||||
printk_debug("Device = %d, A Offset = %d, B Offset = %d\n",
|
||||
i,adj_a[i],adj_b[i]);
|
||||
}
|
||||
/* RDRAM Device Timing */
|
||||
pcibios_write_config_byte(I860_MCH_BUS,I860_MCH_DEVFN,MCH_RDT,rdt);
|
||||
|
||||
for(i = 0; i < rdram_devices; i++) {
|
||||
rdram_write_reg(0, i, REG_TCDLY1, tcdly1[adj_a[i]], tcdly1[adj_b[i]]);
|
||||
rdram_write_reg(0, i, REG_TPARM, tparm[adj_a[i]], tparm[adj_b[i]]);
|
||||
}
|
||||
|
||||
display_rdram_regs_tparm(rdram_chips);
|
||||
#if 0
|
||||
rdram_run_command(0, 0, CMD_MCH_RAC_LOAD_RACA_CONFIG);
|
||||
rdram_run_command(0, 0, CMD_MCH_RAC_LOAD_RACB_CONFIG);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
static void rdram_set_clear_reset(void)
|
||||
{
|
||||
int delay=0;
|
||||
int tcycle;
|
||||
|
||||
rdram_write_reg(0, BCAST, REG_TEST78, 0x04, 0x04);
|
||||
rdram_write_reg(0, BCAST, REG_TEST34, 0x40, 0x40);
|
||||
rdram_run_command(0, BCAST, CMD_RDRAM_SET_RESET);
|
||||
/* Compute max of 16 * Tscycle or 2816 * Tcycle */
|
||||
if(spd_mhz_min[0]) {
|
||||
tcycle=(999+spd_mhz_min[0])/spd_mhz_min[0];
|
||||
delay=tcycle*2816;
|
||||
}
|
||||
if(delay>(16*TSCYCLE_SLOW))
|
||||
ndelay(delay);
|
||||
else
|
||||
ndelay(16*TSCYCLE_SLOW);
|
||||
rdram_run_command(0, BCAST, CMD_RDRAM_CLEAR_RESET);
|
||||
rdram_write_reg(0, BCAST, REG_TEST34, 0, 0);
|
||||
rdram_write_reg(0, BCAST, REG_TEST78, 0, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
- ro CNFGA, CNFGB,
|
||||
- ok REFB, REFR
|
||||
- SKIP, TEST79
|
||||
TEST34, TEST78,
|
||||
TEST77,
|
||||
TCYCLE,
|
||||
INIT,
|
||||
DEVID,
|
||||
PDNXA, PDNX, NAPX, TPARM, TCDLY1, TFRM, REG_CCA, REG, CCB
|
||||
*/
|
||||
static void rdram_init(int rdram_devices)
|
||||
{
|
||||
u16 tcycle;
|
||||
u16 pdnxa,pdnxb,pdnx,napx,napxa,napxb;
|
||||
u16 tfrm;
|
||||
int i;
|
||||
|
||||
/* 3.1/3.2 RDRAM SIO reset */
|
||||
rdram_run_command(0, 0, CMD_RDRAM_SIO_RESET);
|
||||
|
||||
/* 3.3 Clear TEST77 */
|
||||
rdram_write_reg(0, BCAST, REG_TEST77, 0, 0);
|
||||
|
||||
/* 3.4 Write Tcycle */
|
||||
/* Calculate the Tcycle */
|
||||
for(tcycle=spd_mhz_max[0],i=1;i<4;i++)
|
||||
if(spd_mhz_max[i]&&(tcycle>spd_mhz_max[i]))
|
||||
tcycle=spd_mhz_max[i];
|
||||
tcycle = 15625 / tcycle;
|
||||
rdram_write_reg(0, BCAST, REG_TCYCLE, tcycle, tcycle);
|
||||
printk_debug("Tcycle = %x\n",tcycle);
|
||||
|
||||
/* 3.5 Set SDEVID */
|
||||
set_sdevid(rdram_devices);
|
||||
|
||||
/* 3.6 Set DEVID */
|
||||
set_devid(rdram_devices);
|
||||
|
||||
/* 3.7 Write PDNX, PDNXA Registers */
|
||||
/* tscycle=10ns or <= 100MHz MCH datasheet pg 156 */
|
||||
for(pdnxa=(u16)spd_pdnxa_max[0],i=1;i<4;i++)
|
||||
if(pdnxa<spd_pdnxa_max[i])
|
||||
pdnxa=spd_pdnxa_max[i];
|
||||
for(pdnxb=(u16)spd_pdnxb_max[0],i=1;i<4;i++)
|
||||
if(pdnxb<(u16)spd_pdnxb_max[i])
|
||||
pdnxb=(u16)spd_pdnxb_max[i];
|
||||
/* spd-31*1000 + 635 as a round up factor / (64*SCK) */
|
||||
pdnx=(pdnxa*1000+635)/640;
|
||||
printk_debug("PDNXA = %d\n",pdnx);
|
||||
rdram_write_reg(0, BCAST, REG_PDNXA, pdnx, pdnx);
|
||||
/* spd-31*1000 + spd-32*64 + 2555 round up factor / (256*SCK) */
|
||||
pdnx=((pdnxa*1000)+(pdnxb*64)+2555)/2560;
|
||||
rdram_write_reg(0, BCAST, REG_PDNX, pdnx, pdnx);
|
||||
printk_debug("PDNX = %d\n",pdnx);
|
||||
|
||||
/* 3.8 Write NAPX */
|
||||
/* (1<<10 DQS)+(((spd-33+spd-34)/SCK)<<5)+(spd-33/SCK) */
|
||||
/* find the max values of the spds for napxa and napxb */
|
||||
for(napxa=(u16)spd_napxa_max[0],i=1;i<4;i++)
|
||||
if(napxa<spd_napxa_max[i])
|
||||
napxa=spd_napxa_max[i];
|
||||
for(napxb=(u16)spd_napxb_max[0],i=1;i<4;i++)
|
||||
if(napxb<spd_napxb_max[i])
|
||||
napxb=spd_napxb_max[i];
|
||||
if(spd_misc_conf[0]&1)
|
||||
napx=(1<<10);
|
||||
else
|
||||
napx=0;
|
||||
napx+=(((napxa+napxb+9)/10)<<5)+((napxa+9)/10);
|
||||
rdram_write_reg(0, BCAST, REG_NAPX, napx, napx);
|
||||
printk_debug("NAPX = %x\n",napx);
|
||||
|
||||
/* 3.9 Write TPARM */
|
||||
/* Use max times for initial timing. Then redo in step 6.2 */
|
||||
rdram_write_reg(0, BCAST, REG_TPARM, 0x3a, 0x3a);
|
||||
|
||||
/* 3.10 Write TCDLY1 Register */
|
||||
/* Use max times for initial timing. Then redo in step 6.2 */
|
||||
rdram_write_reg(0, BCAST, REG_TCDLY1, 2, 2);
|
||||
|
||||
/* 3.11 Write TFRM Register */
|
||||
/* As far as I can tell the equation for TFRM is correct, */
|
||||
/* however, the documention is not clear, and some assumptions */
|
||||
/* were made. If ram does not work, this would be a good */
|
||||
/* CHECKME */
|
||||
if(spd_rcd_min[0]) {
|
||||
tfrm = spd_rcd_min[0] - 1;
|
||||
while(tfrm > 10)
|
||||
tfrm-=4;
|
||||
}
|
||||
else {
|
||||
tfrm = 9;
|
||||
}
|
||||
rdram_write_reg(0, BCAST, REG_TFRM, tfrm, tfrm);
|
||||
|
||||
/* 3.12 SETR/CLRR */
|
||||
rdram_set_clear_reset();
|
||||
|
||||
/* 3.13 Write CCA and CCB Registers */
|
||||
/* Program all Current controll registers with
|
||||
* an initial approximation. 1/2 their maximum is recommended.
|
||||
*/
|
||||
rdram_write_reg(0, BCAST, REG_CCA, 0x40, 0x40);
|
||||
rdram_write_reg(0, BCAST, REG_CCB, 0x40, 0x40);
|
||||
|
||||
/* 3.14 Powerdown Exit */
|
||||
/* test is S28IECO is set, if yes power up ram from PDN state */
|
||||
if(spd_misc_conf[0]&4)
|
||||
rdram_run_command(0, BCAST, CMD_RDRAM_POWERDOWN_EXIT);
|
||||
|
||||
/* 3.15 SETF */
|
||||
rdram_run_command(0, BCAST, CMD_SET_FAST_CLK);
|
||||
}
|
||||
|
||||
void mch_init(void)
|
||||
{
|
||||
u8 byte;
|
||||
u16 word;
|
||||
u16 top;
|
||||
int bits1,bits2;
|
||||
int reg,reg_last,dev;
|
||||
|
||||
/* Program Group Attribute Registers */
|
||||
/* Calculate the GAR value */
|
||||
bits1=(spd_row_col[0]>>4)+(spd_row_col[0]&0x0f)+spd_banks[0];
|
||||
byte=0x80;
|
||||
if(bits1==21) {
|
||||
byte=0x84;
|
||||
spd_size[0]=32;
|
||||
}
|
||||
else if(bits1==20) {
|
||||
byte=0x82;
|
||||
spd_size[0]=16;
|
||||
}
|
||||
if(byte!=0x80) {
|
||||
if(spd_banks[0]==5) byte|=0x10;
|
||||
if((spd_row_col[0]&0x0f)==7) byte|=0x40;
|
||||
}
|
||||
for(reg=dev=0;dev<spd_devices[0];reg++,dev+=4) {
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, mch_gar[reg], byte);
|
||||
printk_debug("GAR reg = %x, byte = %x\n",mch_gar[reg],byte);
|
||||
}
|
||||
/* Test for 2nd set of rimms */
|
||||
bits2=(spd_row_col[1]>>4)+(spd_row_col[1]&0x0f)+spd_banks[1];
|
||||
byte=0x80;
|
||||
if(bits2==21) {
|
||||
byte=0x84;
|
||||
spd_size[1]=32;
|
||||
}
|
||||
else if(bits2==20) {
|
||||
byte=0x82;
|
||||
spd_size[1]=16;
|
||||
}
|
||||
if(byte!=0x80) {
|
||||
if(spd_banks[1]==5) byte|=0x10;
|
||||
if((spd_row_col[1]&0x0f)==7) byte|=0x40;
|
||||
}
|
||||
for(dev=0;dev<spd_devices[1];reg++,dev+=4) {
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, mch_gar[reg], byte);
|
||||
printk_debug("GAR reg = %x, byte = %x\n",mch_gar[reg],byte);
|
||||
}
|
||||
|
||||
/* The rest are not used because the board has 4 slots & no repeter hubs */
|
||||
for(;reg<16;reg++) {
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, mch_gar[reg], 0x80);
|
||||
printk_debug("GAR reg = %x, byte = 0x80\n",mch_gar[reg]);
|
||||
}
|
||||
|
||||
/* Memory Controller Hub Configuration */
|
||||
/* 1 System Bus Stop Grant,300 or 400Mhz, Non-ECC, MDA Not Present, Apic Enabled */
|
||||
pcibios_read_config_word(I860_MCH_BUS, I860_MCH_DEVFN, MCH_MCHCFG, &word);
|
||||
word &= ~((7 << 13) | (1 << 9) | (3 << 7) | (1 << 5) | (1 << 1));
|
||||
if(((spd_mhz_max[0]==400)&&(spd_mhz_max[1]==400)) ||
|
||||
((spd_mhz_max[0]==400)&&(spd_mhz_max[1]==0)))
|
||||
word |= (1 << 11); /* Sets ram bus speed at 400 mhz, else 300 mhz */
|
||||
pcibios_write_config_word(I860_MCH_BUS, I860_MCH_DEVFN, MCH_MCHCFG, word);
|
||||
|
||||
/* Fixed DRAM Hole Control */
|
||||
/* Disabled */
|
||||
pcibios_read_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_FDHC, &byte);
|
||||
byte &= ~(1 << 7);
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_FDHC, byte);
|
||||
|
||||
/* Programmable Attribute Map */
|
||||
/* All Ram, Except the mandatory VGA hole */
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_PAM0, 0x30);
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_PAM1, 0x33);
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_PAM2, 0x33);
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_PAM3, 0x33);
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_PAM4, 0x33);
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_PAM5, 0x33);
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_PAM6, 0x33);
|
||||
|
||||
/* RDRAM Device Group Boundary Addresses */
|
||||
if(bits1==21) word=16;
|
||||
else word=8;
|
||||
for(reg=dev=0,top=0;dev<spd_devices[0];dev+=4,reg++) {
|
||||
top+=word;
|
||||
pcibios_write_config_word(I860_MCH_BUS, I860_MCH_DEVFN, mch_gba[reg], (reg<<11)|top);
|
||||
printk_debug("GBA reg = %x, word = %x\n",mch_gba[reg],(reg<<11)|top);
|
||||
}
|
||||
|
||||
word=0;
|
||||
if(bits2==21) word=16;
|
||||
else if(bits2==20) word=8;
|
||||
|
||||
for(dev=0;dev<spd_devices[1];dev+=4,reg++) {
|
||||
top+=word;
|
||||
pcibios_write_config_word(I860_MCH_BUS, I860_MCH_DEVFN, mch_gba[reg], (reg<<11)|top);
|
||||
printk_debug("GBA reg = %x, word = %x\n",mch_gba[reg],(reg<<11)|top);
|
||||
}
|
||||
|
||||
/* The rest are filled with the high address */
|
||||
for(reg_last=reg-1;reg<16;reg++) {
|
||||
pcibios_write_config_word(I860_MCH_BUS, I860_MCH_DEVFN, mch_gba[reg], (reg_last<<11)|top);
|
||||
printk_debug("GBA reg = %x, word = %x\n",mch_gba[reg],(reg_last<<11)|top);
|
||||
}
|
||||
|
||||
/* RDRAM Deice Pool Sizeing Register */
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_RDPS, 0x0f);
|
||||
|
||||
/* RDRAM Device Timing */
|
||||
pcibios_write_config_byte(I860_MCH_BUS, I860_MCH_DEVFN, MCH_RDT, 0x8e);
|
||||
|
||||
/* Top of Memory */
|
||||
pcibios_write_config_word(I860_MCH_BUS, I860_MCH_DEVFN, MCH_TOM, top<<8);
|
||||
printk_debug("TOM = %x <<8\n",top);
|
||||
|
||||
/* Error Command Register */
|
||||
/* Disable reporting errors for now */
|
||||
pcibios_write_config_word(I860_MCH_BUS, I860_MCH_DEVFN, MCH_ERRCMD, 0);
|
||||
|
||||
/* SMI Command Register */
|
||||
/* Disable reporting errors for now */
|
||||
pcibios_write_config_word(I860_MCH_BUS, I860_MCH_DEVFN, MCH_SMICMD, 0);
|
||||
|
||||
/* SCI Command Register */
|
||||
/* Disable reporting errors for now */
|
||||
pcibios_write_config_word(I860_MCH_BUS, I860_MCH_DEVFN, MCH_SCICMD, 0);
|
||||
|
||||
/* RDRAM Device Refresh Control */
|
||||
/* Hard coded the faster refrest time to make sure memory is refreshed */
|
||||
pcibios_write_config_word(I860_MCH_BUS, I860_MCH_DEVFN, MCH_DRAMRC, 1);
|
||||
}
|
||||
|
||||
|
||||
static void load_spd_vars(void)
|
||||
{
|
||||
int j;
|
||||
int status;
|
||||
unsigned char byte;
|
||||
u16 max,min;
|
||||
|
||||
for(j = SMBUS_MEM_DEVICE_0; j < SMBUS_MEM_DEVICE_0 + 4; j++) {
|
||||
status = 0;
|
||||
if ((j == 0x1b) || 0) {
|
||||
continue;
|
||||
}
|
||||
status = smbus_read_byte(j, 4, &byte);
|
||||
if (status == 0) {
|
||||
spd_row_col[j-SMBUS_MEM_DEVICE_0]=byte;
|
||||
}
|
||||
status = smbus_read_byte(j, 5, &byte);
|
||||
if (status == 0) {
|
||||
spd_banks[j-SMBUS_MEM_DEVICE_0]=byte&0xf;
|
||||
}
|
||||
status = smbus_read_byte(j, 9, &byte);
|
||||
if (status == 0) {
|
||||
spd_misc_conf[j-SMBUS_MEM_DEVICE_0]=byte;
|
||||
}
|
||||
status = smbus_read_byte(j, 12, &byte);
|
||||
if (status == 0) {
|
||||
spd_rcd_min[j-SMBUS_MEM_DEVICE_0]=byte;
|
||||
}
|
||||
status = smbus_read_byte(j, 31, &byte);
|
||||
if (status == 0) {
|
||||
spd_pdnxa_max[j-SMBUS_MEM_DEVICE_0]=byte;
|
||||
}
|
||||
status = smbus_read_byte(j, 32, &byte);
|
||||
if (status == 0) {
|
||||
spd_pdnxb_max[j-SMBUS_MEM_DEVICE_0]=byte;
|
||||
}
|
||||
status = smbus_read_byte(j, 33, &byte);
|
||||
if (status == 0) {
|
||||
spd_napxa_max[j-SMBUS_MEM_DEVICE_0]=byte;
|
||||
}
|
||||
status = smbus_read_byte(j, 34, &byte);
|
||||
if (status == 0) {
|
||||
spd_napxb_max[j-SMBUS_MEM_DEVICE_0]=byte;
|
||||
}
|
||||
status = smbus_read_byte(j, 35, &byte);
|
||||
if (status == 0) {
|
||||
min=((u16)byte<<4)&0x0f00; /* shift the high 4 bits into the next byte */
|
||||
max=((u16)byte<<8)&0x0f00; /* shift the low 4 bits into the next byte */
|
||||
status = smbus_read_byte(j, 36, &byte);
|
||||
if (status == 0) {
|
||||
spd_mhz_min[j-SMBUS_MEM_DEVICE_0] = min | byte;
|
||||
}
|
||||
status = smbus_read_byte(j, 37, &byte);
|
||||
if (status == 0) {
|
||||
spd_mhz_max[j-SMBUS_MEM_DEVICE_0] = max | byte;
|
||||
}
|
||||
}
|
||||
else {
|
||||
spd_mhz_min[j-SMBUS_MEM_DEVICE_0] = 0;
|
||||
spd_mhz_max[j-SMBUS_MEM_DEVICE_0] = 0;
|
||||
}
|
||||
status = smbus_read_byte(j, 99, &byte);
|
||||
if (status == 0) {
|
||||
spd_devices[j-SMBUS_MEM_DEVICE_0]=byte;
|
||||
}
|
||||
status = smbus_read_byte(j, 100, &byte);
|
||||
if (status == 0) {
|
||||
spd_data_width[j-SMBUS_MEM_DEVICE_0]=byte;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void ram_zap(unsigned long start, unsigned long stop)
|
||||
{
|
||||
unsigned long addr;
|
||||
/*
|
||||
* Fill.
|
||||
*/
|
||||
printk_debug("DRAM zero: %08lx-%08lx\n", start, stop);
|
||||
for(addr = start; addr < stop ; addr += 4) {
|
||||
/* Display address being filled */
|
||||
if ((addr & 0x0fffffff) == 0)
|
||||
printk_spew("%08lx\r", addr);
|
||||
RAM(unsigned long, addr) = 0;
|
||||
};
|
||||
/* Display final address */
|
||||
printk_debug("%08lx\nDRAM filled\n", addr);
|
||||
|
||||
}
|
||||
|
||||
void init_memory(void)
|
||||
{
|
||||
int i,j;
|
||||
int rdram_devices=0;
|
||||
u32 ricm;
|
||||
u16 word;
|
||||
|
||||
load_spd_vars();
|
||||
display_spd_dev_row_col_bank(spd_devices, spd_row_col, spd_banks);
|
||||
for(i=0;i<2;i++) {
|
||||
if(spd_devices&&(spd_devices[i]==spd_devices[i+2])&&
|
||||
(spd_row_col[i]==spd_row_col[i+2])&&
|
||||
(spd_banks[i]==spd_banks[i+2]))
|
||||
rdram_devices+=spd_devices[i];
|
||||
}
|
||||
if(rdram_devices==0){
|
||||
printk_debug("ERROR - Memory Rimms are not matched.\n");
|
||||
for(;;) i=1; /* Freeze the system error */
|
||||
}
|
||||
else {
|
||||
rdram_chips=rdram_devices;
|
||||
}
|
||||
printk_debug("RDRAM Chips = %d\n",rdram_chips);
|
||||
|
||||
/* 1. Start the clocks */
|
||||
rdram_run_command(0, 0, CMD_POWERUP_ALL_SEQUENCE);
|
||||
|
||||
/* 2. RAC initialization */
|
||||
rdram_run_command(0, 0, CMD_MCH_INITIALIZE_RAC);
|
||||
|
||||
/* 3. Rdram initialize */
|
||||
rdram_init(rdram_devices);
|
||||
|
||||
/* 4. Initialize Memory Controller */
|
||||
mch_init();
|
||||
|
||||
/* 6.1 RDRAM Core Initialization */
|
||||
for(i = 0; i < 192; i++) {
|
||||
rdram_run_command(0, BCAST, CMD_RDRAM_REFRESH);
|
||||
}
|
||||
|
||||
/* 5. Rdram Current Control */
|
||||
/* You can disable the final memory initialized bit
|
||||
* to see if this is working and it isn't!
|
||||
* It is close though.
|
||||
* FIXME manual current calibration.
|
||||
*/
|
||||
|
||||
rdram_run_command(0, 0, CMD_MCH_RAC_CURRENT_CALIBRATION);
|
||||
|
||||
/* Do not do the following command. It will cause a lock up */
|
||||
/* rdram_run_command(0, 0, CMD_MANUAL_CURRENT_CALIBRATION); */
|
||||
|
||||
for(i = 0; i < 128; i++) {
|
||||
for(j=0;j<rdram_chips;j++) {
|
||||
rdram_run_command(0, j, CMD_RDRAM_CURRENT_CALIBRATION);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
display_rdram_regs( rdram_chips );
|
||||
#endif
|
||||
|
||||
rdram_run_command(0, BCAST, CMD_TEMP_CALIBRATE_ENABLE);
|
||||
rdram_run_command(0, BCAST, CMD_TEMP_CALIBRATE);
|
||||
|
||||
/* 6.2 RDRAM Read Domain Initialization */
|
||||
rdram_read_domain_initialization(rdram_devices);
|
||||
|
||||
/* 7.0 Remaining init bits (LSR, NSR, PSR) */
|
||||
set_init_bits(rdram_devices);
|
||||
|
||||
/* Final Set the memory initialized bit */
|
||||
pcibios_read_config_dword(I860_MCH_BUS, I860_MCH_DEVFN, MCH_RICM, &ricm);
|
||||
ricm |= RICM_DONE;
|
||||
pcibios_write_config_dword(I860_MCH_BUS, I860_MCH_DEVFN,
|
||||
MCH_RICM, ricm);
|
||||
|
||||
/* Memory Controller Hub Configuration Enable ECC */
|
||||
pcibios_read_config_word(I860_MCH_BUS, I860_MCH_DEVFN, MCH_MCHCFG, &word);
|
||||
word |= (1 << 8);
|
||||
pcibios_write_config_word(I860_MCH_BUS, I860_MCH_DEVFN, MCH_MCHCFG, word);
|
||||
|
||||
/* Set write combine for the memory max of 2 gig */
|
||||
printk_debug("set_var_mtrr\n");
|
||||
set_var_mtrr(0, 0, 2*1024*1024*1024UL, MTRR_TYPE_WRCOMB);
|
||||
|
||||
/* Clear all memory to 0's */
|
||||
total_rdram=(unsigned long)(((unsigned long)spd_size[0]<<21)*spd_devices[0])+
|
||||
(((unsigned long)spd_size[1]<<21)*spd_devices[1]);
|
||||
ram_zap(0,0x0a0000);
|
||||
ram_zap(0x0c0000,(unsigned long)total_rdram);
|
||||
}
|
||||
|
|
@ -2,4 +2,5 @@ object keyboard.o
|
|||
object mc146818rtc.o
|
||||
object isa-dma.o
|
||||
object i8259.o
|
||||
dir ide
|
||||
|
||||
|
|
1
src/pc80/ide/Config
Normal file
1
src/pc80/ide/Config
Normal file
|
@ -0,0 +1 @@
|
|||
object ide.o
|
447
src/pc80/ide/ide.c
Normal file
447
src/pc80/ide/ide.c
Normal file
|
@ -0,0 +1,447 @@
|
|||
/*
|
||||
* UBL, The Universal Talkware Boot Loader
|
||||
* Copyright (C) 2000 Universal Talkware Inc.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Note: Parts of this code grew out of the Openbios effort that was
|
||||
* abandoned. Without the info that we were able to learn from
|
||||
* OpenBios this program would have never worked. We are forever
|
||||
* grateful for those who came before us.
|
||||
*
|
||||
* This code can be retrieved in a machine/human readable form at:
|
||||
*
|
||||
* http://www.talkware.net/GPL/UBL
|
||||
*
|
||||
* Anyone making changes to this code please send them to us so we
|
||||
* can include them in the standard release.
|
||||
*
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <printk.h>
|
||||
#include <string.h>
|
||||
#include "ide.h"
|
||||
|
||||
static __inline__ int wait_for_notbusy(unsigned base) {
|
||||
unsigned i = 0;
|
||||
do {
|
||||
if (((inb_p(IDE_REG_ERROR(base)) & 0x80) != 0x80) &&
|
||||
((inb_p(IDE_REG_STATUS(base)) & 0x80) != 0x80))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
} while (i != 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline__ int wait_for_dataready(unsigned base) {
|
||||
unsigned i = 0;
|
||||
do {
|
||||
if (((inb_p(IDE_REG_ERROR(base)) & 0x80) != 0x80) &&
|
||||
((inb_p(IDE_REG_STATUS(base)) & 0x88) != 0x88))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
i++;
|
||||
} while (i != 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline__ int write_command(
|
||||
unsigned base,
|
||||
ide_command_t command,
|
||||
ide_cmd_param_t * params)
|
||||
{
|
||||
if (wait_for_notbusy(base) != 0) return 1;
|
||||
outb_p(params->precomp, IDE_REG_PRECOMP(base));
|
||||
outb_p(params->sector_count, IDE_REG_SECTOR_COUNT(base));
|
||||
outb_p(params->sector_number, IDE_REG_SECTOR_NUMBER(base));
|
||||
outb_p(params->cylinder & 0xFF, IDE_REG_CYLINDER_LSB(base));
|
||||
outb_p((params->cylinder >> 8) & 0x03, IDE_REG_CYLINDER_MSB(base));
|
||||
outb_p(params->drivehead, IDE_REG_DRIVEHEAD(base));
|
||||
if (wait_for_notbusy(base) != 0) return 1;
|
||||
outb_p(command, IDE_REG_COMMAND(base));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ide_shutdown(void)
|
||||
{
|
||||
outb_p(IDE_CMD_STANDBY_IMMEDIATE, IDE_REG_COMMAND(IDE_BASE1));
|
||||
outb_p(IDE_CMD_STANDBY_IMMEDIATE2, IDE_REG_COMMAND(IDE_BASE1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ide_read_data(unsigned base, void * buf, size_t size) {
|
||||
register unsigned short * ptr = (unsigned short *) buf;
|
||||
if (wait_for_dataready(base)) {
|
||||
printk_debug("data not ready...\n");
|
||||
return 1;
|
||||
}
|
||||
while (size > 1) {
|
||||
*ptr++ = inw_p(IDE_REG_DATA(base));
|
||||
size -= sizeof(unsigned short);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ide_write_data(unsigned base, void * buf, size_t size) {
|
||||
register unsigned short * ptr = (unsigned short *) buf;
|
||||
if (wait_for_dataready(base)) return 1;
|
||||
while (size > 1) {
|
||||
outw_p(*ptr, IDE_REG_DATA(base));
|
||||
ptr++;
|
||||
size -= sizeof(unsigned short);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
harddisk_info_t harddisk_info[NUM_HD];
|
||||
|
||||
static char buffer[512];
|
||||
|
||||
static int init_drive(unsigned base, int driveno) {
|
||||
volatile int delay;
|
||||
ide_cmd_param_t cmd = IDE_DEFAULT_COMMAND;
|
||||
unsigned char command_val;
|
||||
//unsigned int idx;
|
||||
//int retval;
|
||||
unsigned short* drive_info;
|
||||
|
||||
harddisk_info[driveno].controller_port = base;
|
||||
harddisk_info[driveno].num_heads = 0u;
|
||||
harddisk_info[driveno].num_cylinders = 0u;
|
||||
harddisk_info[driveno].num_sectors_per_track = 0u;
|
||||
harddisk_info[driveno].num_sectors = 0ul;
|
||||
harddisk_info[driveno].address_mode = IDE_DH_CHS;
|
||||
harddisk_info[driveno].drive_exists = 0;
|
||||
|
||||
cmd.drivehead = IDE_DH_DEFAULT | IDE_DH_HEAD(0) | IDE_DH_CHS |
|
||||
IDE_DH_DRIVE(driveno);
|
||||
write_command(base, IDE_CMD_GET_INFO, &cmd);
|
||||
if ((inb_p(IDE_REG_STATUS(base)) & 1) != 0) {
|
||||
/* Well, if that command didn't work, we probably don't have drive. */
|
||||
printk_debug("Drive %d: detect FAILED\n", driveno);
|
||||
return 1;
|
||||
}
|
||||
ide_read_data(base, buffer, IDE_SECTOR_SIZE);
|
||||
|
||||
/* Now suck the data out */
|
||||
#if 0
|
||||
harddisk_info[driveno].num_heads = *((unsigned short *) (buffer + 0x6E));
|
||||
harddisk_info[driveno].num_cylinders = *((unsigned short *) (buffer + 0x6C));
|
||||
harddisk_info[driveno].num_sectors_per_track =
|
||||
*((unsigned short *) (buffer + 0x70));
|
||||
harddisk_info[driveno].num_sectors = *((unsigned int *) (buffer + 0x72));
|
||||
#else
|
||||
drive_info = (unsigned short*)buffer;
|
||||
harddisk_info[driveno].num_heads = drive_info[3];
|
||||
harddisk_info[driveno].num_cylinders = drive_info[1];
|
||||
harddisk_info[driveno].num_sectors_per_track = drive_info[6];
|
||||
harddisk_info[driveno].num_sectors = *((unsigned int*)&(drive_info[60]));
|
||||
#endif
|
||||
harddisk_info[driveno].drive_exists = 1;
|
||||
|
||||
printk_debug(__FUNCTION__ " sectors_per_track=[%d], num_heads=[%d], num_cylinders=[%d]\n",
|
||||
harddisk_info[driveno].num_sectors_per_track,
|
||||
harddisk_info[driveno].num_heads,
|
||||
harddisk_info[driveno].num_cylinders);
|
||||
|
||||
#define HD harddisk_info[driveno]
|
||||
if(drive_info[49] != 0) {
|
||||
printk_debug("IDE%d %d/%d/%d cap: %04x\n",
|
||||
(int)driveno, (int)HD.num_heads, (int)HD.num_cylinders, (int)HD.num_sectors_per_track,
|
||||
(int) drive_info[49]);
|
||||
}
|
||||
|
||||
// printk_debug("drive %d detected heads=0x%X(%u) cyl=0x%X(%u) sec/trk="
|
||||
// "0x%X(%u) sects=0x%X(%u)\n", (int)driveno, (int)HD.num_heads, (int)HD.num_heads,
|
||||
// HD.num_cylinders, (int)HD.num_cylinders, (int)HD.num_sectors_per_track,
|
||||
// HD.num_sectors_per_track, (int)HD.num_sectors, (int)HD.num_sectors);
|
||||
|
||||
// printk_debug" capability=[%04x]\n", (int)drive_info[49]);
|
||||
|
||||
if (drive_info[49] & 0x200) { /* bit 9 of capability word is lba supported bit */
|
||||
harddisk_info[driveno].address_mode = IDE_DH_LBA;
|
||||
} else {
|
||||
harddisk_info[driveno].address_mode = IDE_DH_CHS;
|
||||
}
|
||||
// harddisk_info[driveno].address_mode = IDE_DH_CHS;
|
||||
|
||||
/* Set up the Extended control register */
|
||||
if (harddisk_info[driveno].num_heads > 8) {
|
||||
command_val = 0x0A;
|
||||
} else {
|
||||
command_val = 0x02;
|
||||
}
|
||||
|
||||
outb_p(command_val, IDE_REG_CONTROL(base));
|
||||
|
||||
/* Execute the drive diagnostics command */
|
||||
write_command(base, IDE_CMD_DRIVE_DIAG, &cmd);
|
||||
if ((inb_p(IDE_REG_STATUS(base)) & 1) != 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Reset the bus (again) */
|
||||
outb_p(cmd.drivehead, IDE_REG_DRIVEHEAD(base));
|
||||
outb_p(0x04, IDE_REG_CONTROL(base));
|
||||
for (delay = 0x100; delay > 0; --delay);
|
||||
outb_p(command_val, IDE_REG_CONTROL(base));
|
||||
|
||||
/* Now do a drive recalibrate */
|
||||
write_command(base, IDE_CMD_RECALIBRATE, &cmd);
|
||||
if ((inb_p(IDE_REG_STATUS(base)) & 1) != 0) {
|
||||
return 1;
|
||||
}
|
||||
(void)wait_for_notbusy(base);
|
||||
|
||||
/* Set device parameters */
|
||||
cmd.sector_count = harddisk_info[driveno].num_sectors_per_track;
|
||||
cmd.drivehead = IDE_DH_DEFAULT |
|
||||
IDE_DH_HEAD(harddisk_info[driveno].num_heads) |
|
||||
IDE_DH_DRIVE(driveno) |
|
||||
harddisk_info[driveno].address_mode;
|
||||
write_command(base, IDE_CMD_SET_PARAMS, &cmd);
|
||||
|
||||
/* Set multiple mode */
|
||||
cmd.sector_count = 0x10; /* Single-word DMA, mode 0 */
|
||||
cmd.drivehead = IDE_DH_DEFAULT |
|
||||
IDE_DH_HEAD(0) |
|
||||
IDE_DH_DRIVE(driveno) |
|
||||
harddisk_info[driveno].address_mode;
|
||||
write_command(base, IDE_CMD_SET_MULTIMODE, &cmd);
|
||||
|
||||
/* Make sure command is still OK */
|
||||
outb_p(command_val, IDE_REG_CONTROL(base));
|
||||
|
||||
/* Set parameters _again_ */
|
||||
cmd.sector_count = harddisk_info[driveno].num_sectors_per_track;
|
||||
cmd.drivehead = IDE_DH_DEFAULT |
|
||||
IDE_DH_HEAD(harddisk_info[driveno].num_heads) |
|
||||
IDE_DH_DRIVE(driveno) |
|
||||
harddisk_info[driveno].address_mode;
|
||||
write_command(base, IDE_CMD_SET_PARAMS, &cmd);
|
||||
|
||||
/* Make sure command is still OK */
|
||||
outb_p(command_val, IDE_REG_CONTROL(base));
|
||||
|
||||
#if 0
|
||||
/* Exercise the drive to see if it works OK */
|
||||
printk_debug("Exercising HardDisk- buffer=0x%08lX\n", (unsigned long) buffer);
|
||||
outb_p(0x42, 0xeb);
|
||||
while (1) {
|
||||
for (idx = 0; idx < harddisk_info[driveno].num_sectors; ++idx) {
|
||||
outb_p(idx & 0xFF, 0x80);
|
||||
retval = ide_read_sector(driveno, buffer, idx);
|
||||
if (retval != 0) {
|
||||
printk_debug("readsector(driveno=%d, sector=%lu) returned %d!\n",
|
||||
driveno, (unsigned long) idx, retval);
|
||||
}
|
||||
}
|
||||
printk_debug("Exercise complete!\n");
|
||||
outb(0x42, 0xeb);
|
||||
}
|
||||
#endif /* 0 */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int init_controller(unsigned base, int basedrive) {
|
||||
volatile int delay;
|
||||
|
||||
/* First, check to see if the controller even exists */
|
||||
outb_p(0x5, IDE_REG_SECTOR_COUNT(base));
|
||||
if (inb_p(IDE_REG_SECTOR_COUNT(base)) != 0x5) {
|
||||
printk_debug("Controller %d: detect FAILED (1)\n", basedrive / 2);
|
||||
return -1;
|
||||
}
|
||||
outb_p(0xA, IDE_REG_SECTOR_COUNT(base));
|
||||
if (inb_p(IDE_REG_SECTOR_COUNT(base)) != 0xA) {
|
||||
printk_debug("Controller %d: detect FAILED (2)\n", basedrive / 2);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Reset the system */
|
||||
outb_p(0x4, IDE_REG_CONTROL(base));
|
||||
for (delay = 0x100; delay > 0; --delay);
|
||||
outb_p(0x0, IDE_REG_CONTROL(base));
|
||||
|
||||
/* Now initialize the individual drives */
|
||||
init_drive(base, basedrive);
|
||||
init_drive(base, basedrive+1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int ide_init(void) {
|
||||
|
||||
outb_p(0x42, 0xEB);
|
||||
printk_debug ("I am now initializing the ide system\n");
|
||||
|
||||
if(init_controller(IDE_BASE1, 0) < 0) {
|
||||
printk_debug ("Initializing the main controller failed!\n");
|
||||
/* error return error */
|
||||
return -1;
|
||||
};
|
||||
|
||||
#if (NUM_HD > 3)
|
||||
init_controller(IDE_BASE2, 2);
|
||||
#endif
|
||||
|
||||
#if (NUM_HD > 5)
|
||||
init_controller(IDE_BASE3, 4);
|
||||
#endif
|
||||
|
||||
#if (NUM_HD > 7)
|
||||
init_controller(IDE_BASE4, 6);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* read a sector or a partial sector */
|
||||
int ide_read_sector(int drive, void * buffer, unsigned int block, int byte_offset,
|
||||
int n_bytes) {
|
||||
ide_cmd_param_t cmd = IDE_DEFAULT_COMMAND;
|
||||
unsigned base;
|
||||
unsigned char sect_buffer[IDE_SECTOR_SIZE];
|
||||
unsigned int track;
|
||||
int status;
|
||||
int address_mode = harddisk_info[drive].address_mode;
|
||||
|
||||
/*
|
||||
printk_debug(__FUNCTION__ " drive[%d], buffer[%08x], block[%08x], offset[%d], n_bytes[%d]\n",
|
||||
drive, buffer, block, byte_offset, n_bytes);
|
||||
*/
|
||||
// printk_debug(__FUNCTION__ " block(%08x) to addr(%08x)\r", block, (int)buffer);
|
||||
if ((drive < 0) || (drive >= NUM_HD) ||
|
||||
(harddisk_info[drive].drive_exists == 0))
|
||||
{
|
||||
printk_debug("unknown drive\n");
|
||||
return 1;
|
||||
}
|
||||
base = harddisk_info[drive].controller_port;
|
||||
|
||||
if (harddisk_info[drive].num_heads > 8) {
|
||||
outb_p(0xA, IDE_REG_CONTROL(base));
|
||||
} else {
|
||||
outb_p(0x2, IDE_REG_CONTROL(base));
|
||||
}
|
||||
|
||||
cmd.sector_count = 1;
|
||||
|
||||
if (address_mode == IDE_DH_CHS) {
|
||||
track = block / harddisk_info[drive].num_sectors_per_track;
|
||||
|
||||
cmd.sector_number = 1+(block % harddisk_info[drive].num_sectors_per_track);
|
||||
cmd.cylinder = track / harddisk_info[drive].num_heads;
|
||||
cmd.drivehead = IDE_DH_DEFAULT |
|
||||
IDE_DH_HEAD(track % harddisk_info[drive].num_heads) |
|
||||
IDE_DH_DRIVE(drive) |
|
||||
IDE_DH_CHS;
|
||||
/*
|
||||
printk_debug(__FUNCTION__ " CHS: track=[%d], sector_number=[%d], cylinder=[%d]\n",
|
||||
track, cmd.sector_number, cmd.cylinder);
|
||||
*/
|
||||
} else {
|
||||
#if 1
|
||||
cmd.sector_number = block & 0xff; /* lower byte of block (lba) */
|
||||
cmd.cylinder = (block >> 8) & 0xffff; /* middle 2 bytes of block (lba) */
|
||||
cmd.drivehead = IDE_DH_DEFAULT | /* set bits that must be on */
|
||||
((block >> 24) & 0x0f) | /* lower nibble of byte 3 of block */
|
||||
IDE_DH_DRIVE(drive) |
|
||||
IDE_DH_LBA;
|
||||
#else
|
||||
cmd.sector_number = (block >> 24) & 0xff; /* byte 0 of block (lba) */
|
||||
cmd.cylinder = (block >> 8) & 0xffff; /* bytes 1 & 2 of block (lba) */
|
||||
cmd.drivehead = IDE_DH_DEFAULT | /* set bits that must be on */
|
||||
((block >> 4) & 0x0f) | /* upper nibble of byte 3 of block */
|
||||
IDE_DH_DRIVE(drive) |
|
||||
IDE_DH_LBA;
|
||||
#endif
|
||||
/*
|
||||
printk_debug(__FUNCTION__ " LBA: drivehead[%0x], cylinder[%04x], sector[%0x], block[%8x]\n",
|
||||
cmd.drivehead, cmd.cylinder, cmd.sector_number, block & 0x0fffffff);
|
||||
*/
|
||||
}
|
||||
|
||||
write_command(base, IDE_CMD_READ_MULTI_RETRY, &cmd);
|
||||
if ((inb_p(IDE_REG_STATUS(base)) & 1) != 0) {
|
||||
printk_debug("ide not ready...\n");
|
||||
return 1;
|
||||
}
|
||||
if (n_bytes != IDE_SECTOR_SIZE) {
|
||||
status = ide_read_data(base, sect_buffer, IDE_SECTOR_SIZE);
|
||||
if (status == 0) {
|
||||
memcpy(buffer, sect_buffer+byte_offset, n_bytes);
|
||||
}
|
||||
} else {
|
||||
status = ide_read_data(base, buffer, IDE_SECTOR_SIZE);
|
||||
}
|
||||
// printk_debug(__FUNCTION__ " status = [%d]\n", status);
|
||||
return status;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* read a sector or a partial sector */
|
||||
int ide_read_sector(int drive, void * buffer, unsigned int block, int byte_offset,
|
||||
int n_bytes) {
|
||||
ide_cmd_param_t cmd = IDE_DEFAULT_COMMAND;
|
||||
unsigned base;
|
||||
unsigned char sect_buffer[IDE_SECTOR_SIZE];
|
||||
unsigned int track;
|
||||
int status;
|
||||
|
||||
if ((drive < 0) || (drive >= NUM_HD) ||
|
||||
(harddisk_info[drive].drive_exists == 0))
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
base = harddisk_info[drive].controller_port;
|
||||
|
||||
if (harddisk_info[drive].num_heads > 8) {
|
||||
outb_p(0xA, IDE_REG_CONTROL(base));
|
||||
} else {
|
||||
outb_p(0x2, IDE_REG_CONTROL(base));
|
||||
}
|
||||
|
||||
track = block / harddisk_info[drive].num_sectors_per_track;
|
||||
|
||||
cmd.sector_count = 1;
|
||||
cmd.sector_number = 1+(block % harddisk_info[drive].num_sectors_per_track);
|
||||
cmd.cylinder = track % harddisk_info[drive].num_heads;
|
||||
cmd.drivehead = IDE_DH_DEFAULT |
|
||||
IDE_DH_HEAD(track / harddisk_info[drive].num_heads) |
|
||||
IDE_DH_DRIVE(drive) |
|
||||
IDE_DH_CHS;
|
||||
|
||||
// printk_debug(__FUNCTION__ " track=[%d], sector_number=[%d], cylinder=[%d]\n",
|
||||
// track, cmd.sector_number, cmd.cylinder);
|
||||
write_command(base, IDE_CMD_READ_MULTI_RETRY, &cmd);
|
||||
if ((inb_p(IDE_REG_STATUS(base)) & 1) != 0) {
|
||||
return 1;
|
||||
}
|
||||
if (n_bytes != IDE_SECTOR_SIZE) {
|
||||
status = ide_read_data(base, sect_buffer, IDE_SECTOR_SIZE);
|
||||
if (status == 0) {
|
||||
memcpy(buffer, sect_buffer+byte_offset, n_bytes);
|
||||
}
|
||||
} else {
|
||||
status = ide_read_data(base, buffer, IDE_SECTOR_SIZE);
|
||||
}
|
||||
// printk_debug(__FUNCTION__ " status = [%d]\n", status);
|
||||
return status;
|
||||
}
|
||||
#endif
|
|
@ -1,7 +1,9 @@
|
|||
object fill_inbuf.o
|
||||
object rom_fill_inbuf.o
|
||||
object docmil_fill_inbuf.o
|
||||
#object docplus_fill_inbuf.o
|
||||
object tsunami_tigbus_rom_fill_inbuf.o
|
||||
object serial_fill_inbuf.o
|
||||
object tftp_fill_inbuf.o
|
||||
driver rom_fill_inbuf.o USE_GENERIC_ROM
|
||||
driver docmil_fill_inbuf.o
|
||||
#driver docplus_fill_inbuf.o
|
||||
driver tsunami_tigbus_rom_fill_inbuf.o USE_TSUNAMI_TIGBUS_ROM
|
||||
driver serial_fill_inbuf.o USE_SERIAL_FILL_INBUF
|
||||
driver tftp_fill_inbuf.o USE_TFTP
|
||||
driver floppy_fill_inbuf.o BOOT_FLOPPY
|
||||
driver ide_fill_inbuf.o BOOT_IDE
|
||||
#object read_bytes.o
|
||||
|
|
|
@ -20,6 +20,10 @@
|
|||
#define DOC_MIL_BASE 0xffffe000
|
||||
#endif
|
||||
|
||||
static unsigned char *inbuf; /* input buffer */
|
||||
static unsigned int insize; /* valid bytes in inbuf */
|
||||
static unsigned int inptr; /* index of next byte to be processed in inbuf */
|
||||
|
||||
static unsigned char *nvram;
|
||||
static int block_count;
|
||||
static int firstfill = 1;
|
||||
|
@ -53,7 +57,7 @@ reset_doc()
|
|||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
static int
|
||||
fill_inbuf(void)
|
||||
{
|
||||
#ifdef CHECK_DOC_MIL
|
||||
|
@ -373,7 +377,7 @@ static int DoCMil_is_alias(volatile char *docptr1, volatile char *docptr2)
|
|||
}
|
||||
|
||||
#if 0
|
||||
int WriteBlockECC(volatile char *docptr, unsigned int block, const char *buf)
|
||||
static int WriteBlockECC(volatile char *docptr, unsigned int block, const char *buf)
|
||||
{
|
||||
unsigned char eccbuf[6];
|
||||
volatile char dummy;
|
||||
|
@ -458,7 +462,7 @@ int WriteBlockECC(volatile char *docptr, unsigned int block, const char *buf)
|
|||
}
|
||||
|
||||
#endif
|
||||
int ReadBlockECC( volatile unsigned char *docptr, unsigned int block, char *buf)
|
||||
static int ReadBlockECC( volatile unsigned char *docptr, unsigned int block, char *buf)
|
||||
{
|
||||
int i, ret;
|
||||
volatile char dummy;
|
||||
|
@ -591,4 +595,46 @@ memcpy_from_doc_mil(void *dest, const void *src, size_t n)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
/* FIXME this is a very lazy ugly port of the new interface to the doc millenium
|
||||
* find a good way to implement this...
|
||||
*/
|
||||
|
||||
#define get_byte() (inptr < insize ? inbuf[inptr++] : fill_inbuf())
|
||||
|
||||
static int init_bytes(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static void fini_bytes(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
|
||||
{
|
||||
byte_offset_t bytes = 0;
|
||||
unsigned char *dest = vdest;
|
||||
while(bytes < count) {
|
||||
*(dest++) = get_byte();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static byte_offset_t skip_bytes(byte_offset_t count)
|
||||
{
|
||||
byte_offset_t bytes = 0;
|
||||
while(bytes < count) {
|
||||
unsigned char byte;
|
||||
byte = get_byte();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct stream doc_mil_stream __stream = {
|
||||
.init = init_bytes,
|
||||
.read = read_bytes,
|
||||
.skip = skip_bytes,
|
||||
.fini = fini_bytes,
|
||||
}
|
||||
|
||||
#endif /* USE_DOC_MIL */
|
||||
|
|
44
src/rom/floppy_fill_inbuf.c
Normal file
44
src/rom/floppy_fill_inbuf.c
Normal file
|
@ -0,0 +1,44 @@
|
|||
#include <printk.h>
|
||||
#include <stdlib.h>
|
||||
#include <subr.h>
|
||||
#include <stddef.h>
|
||||
#include <rom/read_bytes.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <floppy_subr.h>
|
||||
|
||||
static unsigned long offset;
|
||||
|
||||
static int init_bytes(void)
|
||||
{
|
||||
offset = 0;
|
||||
return floppy_init();
|
||||
}
|
||||
|
||||
static void fini_bytes(void)
|
||||
{
|
||||
floppy_fini();
|
||||
}
|
||||
|
||||
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
|
||||
{
|
||||
byte_offset_t len;
|
||||
len = floppy_read(vdest, offset, count);
|
||||
if (len > 0) {
|
||||
offset += len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static byte_offset_t skip_bytes(byte_offset_t count)
|
||||
{
|
||||
offset += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct stream floppy_bytes __stream = {
|
||||
.init = init_bytes,
|
||||
.read = read_bytes,
|
||||
.skip = skip_bytes,
|
||||
.fini = fini_bytes,
|
||||
};
|
84
src/rom/ide_fill_inbuf.c
Normal file
84
src/rom/ide_fill_inbuf.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include <printk.h>
|
||||
#include <stdlib.h>
|
||||
#include <subr.h>
|
||||
#include <stddef.h>
|
||||
#include <rom/read_bytes.h>
|
||||
#include <delay.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <floppy_subr.h>
|
||||
|
||||
/* read a sector or a partial sector */
|
||||
extern int ide_read_sector(int drive, void * buffer, unsigned int block, int byte_offset,
|
||||
int n_bytes);
|
||||
extern int ide_init(void);
|
||||
|
||||
|
||||
|
||||
static unsigned long offset;
|
||||
static int init_bytes(void)
|
||||
{
|
||||
int i;
|
||||
printk_debug ("Trying polled ide\n");
|
||||
printk_debug ("Waiting for ide disks to spin up\n");
|
||||
printk_debug ("This is a hard coded delay and longer than necessary.\n");
|
||||
for(i = 0; i < 25; i++) {
|
||||
printk_debug(".");
|
||||
delay(1);
|
||||
}
|
||||
printk_debug("\n");
|
||||
offset = 0;
|
||||
return ide_init();
|
||||
}
|
||||
|
||||
static void fini_bytes(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static byte_offset_t ide_read(void *vdest, byte_offset_t offset, byte_offset_t count)
|
||||
{
|
||||
byte_offset_t bytes = 0;
|
||||
unsigned char *dest = vdest;
|
||||
while(bytes < count) {
|
||||
unsigned int block, byte_offset, len;
|
||||
int result;
|
||||
block = offset / 512;
|
||||
byte_offset = offset %512;
|
||||
len = 512 - byte_offset;
|
||||
if (len > (count - bytes)) {
|
||||
len = (count - bytes);
|
||||
}
|
||||
result = ide_read_sector(0, dest, block , byte_offset, len);
|
||||
if (result != 0) {
|
||||
return bytes;
|
||||
}
|
||||
offset += len;
|
||||
bytes += len;
|
||||
dest += len;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
|
||||
{
|
||||
byte_offset_t len;
|
||||
len = ide_read(vdest, offset, count);
|
||||
if (len > 0) {
|
||||
offset += len;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
static byte_offset_t skip_bytes(byte_offset_t count)
|
||||
{
|
||||
offset += count;
|
||||
return count;
|
||||
}
|
||||
|
||||
static struct stream ide_stream __stream = {
|
||||
.init = init_bytes,
|
||||
.read = read_bytes,
|
||||
.skip = skip_bytes,
|
||||
.fini = fini_bytes,
|
||||
};
|
|
@ -1,10 +1,8 @@
|
|||
#ifdef USE_GENERIC_ROM
|
||||
|
||||
#include <printk.h>
|
||||
#include <stdlib.h>
|
||||
#include <subr.h>
|
||||
#include <stddef.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
#include <rom/read_bytes.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
|
@ -16,102 +14,85 @@
|
|||
#define ZKERNEL_MASK 0x0000ffff
|
||||
#endif
|
||||
|
||||
/* The inbuf copy option has been killed... */
|
||||
|
||||
static unsigned char *zkernel_start = (unsigned char *)ZKERNEL_START;
|
||||
static unsigned long zkernel_mask = ZKERNEL_MASK;
|
||||
|
||||
static unsigned char *nvram;
|
||||
static int block_count;
|
||||
static int firstfill = 1;
|
||||
|
||||
#if defined(INBUF_COPY)
|
||||
static unsigned char *ram;
|
||||
#endif
|
||||
static int block_offset;
|
||||
|
||||
#define K64 (64 * 1024)
|
||||
|
||||
int fill_inbuf(void)
|
||||
static int init_bytes(void)
|
||||
{
|
||||
extern unsigned char *inbuf;
|
||||
extern unsigned int insize;
|
||||
extern unsigned int inptr;
|
||||
block_count = 0;
|
||||
block_offset = 0;
|
||||
nvram = zkernel_start;
|
||||
|
||||
if (firstfill) {
|
||||
block_count = 0;
|
||||
firstfill = 0;
|
||||
#ifdef INBUF_COPY
|
||||
ram = malloc(K64);
|
||||
#endif
|
||||
}
|
||||
printk_debug("%6d:%s() - zkernel_start:0x%08x "
|
||||
"zkernel_mask:0x%08x\n",
|
||||
__LINE__, __FUNCTION__,
|
||||
zkernel_start, zkernel_mask);
|
||||
|
||||
if (block_count > 31) {
|
||||
printk_emerg( "%6d:%s() - overflowed source buffer\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
inbuf = zkernel_start;
|
||||
inptr = 0;
|
||||
insize = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!block_count) {
|
||||
nvram = zkernel_start;
|
||||
|
||||
#ifdef INBUF_COPY
|
||||
if (!ram) {
|
||||
printk_emerg("%6d:%s() - "
|
||||
"ram malloc failed\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
inbuf = zkernel_start;
|
||||
inptr = 0;
|
||||
insize = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
printk_debug("%6d:%s() - ram buffer:0x%08x\n",
|
||||
__LINE__, __FUNCTION__, ram);
|
||||
#endif
|
||||
printk_debug("%6d:%s() - zkernel_start:0x%08x "
|
||||
"zkernel_mask:0x%08x\n",
|
||||
__LINE__, __FUNCTION__,
|
||||
zkernel_start, zkernel_mask);
|
||||
} else {
|
||||
nvram += K64;
|
||||
|
||||
while (!(zkernel_mask & (1 << block_count))) {
|
||||
printk_debug("%6d:%s() - skipping block %d\n",
|
||||
__LINE__, __FUNCTION__, block_count);
|
||||
|
||||
block_count++;
|
||||
nvram += K64;
|
||||
|
||||
if (block_count > 31) {
|
||||
printk_emerg("%6d:%s() - "
|
||||
"overflowed source buffer\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
inbuf = zkernel_start;
|
||||
inptr = 0;
|
||||
insize = 1;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef INBUF_COPY
|
||||
memcpy(ram, nvram, K64);
|
||||
#endif
|
||||
printk_debug("%6d:%s() - nvram:0x%p block_count:%d\n",
|
||||
__LINE__, __FUNCTION__, nvram, block_count);
|
||||
|
||||
#ifdef INBUF_COPY
|
||||
inbuf = ram;
|
||||
#else
|
||||
inbuf = nvram;
|
||||
#endif
|
||||
insize = K64;
|
||||
inptr = 1;
|
||||
post_code(0xd0 + block_count);
|
||||
block_count++;
|
||||
return inbuf[0];
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif /* USE_GENERIC_ROM */
|
||||
static void fini_bytes(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
static byte_offset_t rom_read_bytes(int cp, void *vdest, byte_offset_t count)
|
||||
{
|
||||
unsigned char *dest = vdest;
|
||||
byte_offset_t bytes = 0;
|
||||
while (bytes < count) {
|
||||
int length;
|
||||
if (block_offset == K64) {
|
||||
block_offset = 0;
|
||||
block_count++;
|
||||
nvram+= K64;
|
||||
}
|
||||
if (!(zkernel_mask & (1 << block_count))) {
|
||||
printk_debug("%6d:%s() - skipping block %d\n",
|
||||
__LINE__, __FUNCTION__, block_count);
|
||||
continue;
|
||||
}
|
||||
if (block_count > 31) {
|
||||
printk_emerg( "%6d:%s() - overflowed source buffer\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
return bytes;
|
||||
}
|
||||
length = K64 - block_offset;
|
||||
if (length > count) {
|
||||
length = count;
|
||||
}
|
||||
if (cp) {
|
||||
memcpy(dest, nvram + block_offset, length);
|
||||
}
|
||||
dest += length;
|
||||
block_offset += length;
|
||||
bytes += length;
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static byte_offset_t skip_bytes(byte_offset_t count)
|
||||
{
|
||||
return rom_read_bytes(0, 0, count);
|
||||
}
|
||||
|
||||
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
|
||||
{
|
||||
return rom_read_bytes(1, vdest, count);
|
||||
}
|
||||
|
||||
static struct stream rom_stream __stream = {
|
||||
.init = init_bytes,
|
||||
.read = read_bytes,
|
||||
.skip = skip_bytes,
|
||||
.fini = fini_bytes,
|
||||
};
|
||||
|
|
|
@ -1,32 +1,36 @@
|
|||
#ifdef USE_SERIAL_FILL_INBUF
|
||||
|
||||
#include <printk.h>
|
||||
#include <stdlib.h>
|
||||
#include <subr.h>
|
||||
#include <stddef.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
#include <rom/read_bytes.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <serial_subr.h>
|
||||
|
||||
|
||||
static int firstfill = 1;
|
||||
static unsigned char *ram;
|
||||
|
||||
#define K64 (64*1024)
|
||||
|
||||
int fill_inbuf(void)
|
||||
static int init_bytes(void)
|
||||
{
|
||||
int rc;
|
||||
if (firstfill) {
|
||||
firstfill = 0;
|
||||
ram = malloc(K64);
|
||||
return 0;
|
||||
}
|
||||
static void fini_bytes(void)
|
||||
{
|
||||
}
|
||||
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
|
||||
{
|
||||
return ttys0_rx_bytes(vdest, count);
|
||||
}
|
||||
static byte_offset_t skip_bytes(byte_offset_t count)
|
||||
{
|
||||
int64_t i;
|
||||
for(i = 0; i < count; i++) {
|
||||
unsigned char byte;
|
||||
byte = ttys0_rx_byte();
|
||||
}
|
||||
inbuf = ram;
|
||||
insize = ttys0_rx_bytes(inbuf, K64);
|
||||
inptr = 1;
|
||||
return inbuf[0];
|
||||
}
|
||||
|
||||
|
||||
#endif /* USE_SERIAL_FILL_INBUF */
|
||||
static struct stream serial_stream __stream = {
|
||||
.init = init_bytes,
|
||||
.read = read_bytes,
|
||||
.skip = skip_bytes,
|
||||
.fini = fini_bytes,
|
||||
};
|
||||
|
|
|
@ -1,54 +1,79 @@
|
|||
#ifdef USE_TFTP
|
||||
|
||||
#include <cpu/p5/io.h>
|
||||
#include <printk.h>
|
||||
#include <stdlib.h>
|
||||
#include <subr.h>
|
||||
#include <stddef.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
#include <rom/read_bytes.h>
|
||||
|
||||
#ifndef DOC_KERNEL_START
|
||||
#define DOC_KERNEL_START 65536
|
||||
#endif
|
||||
static int block_bytes;
|
||||
static int block_offset;
|
||||
static unsigned char *buffer;
|
||||
static int keof;
|
||||
|
||||
static unsigned char *nvram;
|
||||
static int block_count;
|
||||
static int firstfill = 1;
|
||||
extern int tftp_init(const char *name);
|
||||
|
||||
static void memcpy_from_doc_mil(void *dest, const void *src, size_t n);
|
||||
static unsigned char *doc_mil = (unsigned char *) 0xffffe000;
|
||||
#ifdef CHECK_DOC_MIL
|
||||
static unsigned char *checkbuf;
|
||||
#endif /* CHECK_DOC_MIL */
|
||||
|
||||
static unsigned char *ram;
|
||||
#define K64 (64 * 1024)
|
||||
|
||||
|
||||
int fill_inbuf(void)
|
||||
static int init_bytes(void)
|
||||
{
|
||||
extern unsigned char *inbuf;
|
||||
extern unsigned int insize;
|
||||
extern unsigned int inptr;
|
||||
|
||||
int rc;
|
||||
static keof;
|
||||
|
||||
if(keof)
|
||||
return(-1);
|
||||
|
||||
if(firstfill) {
|
||||
tftp_init("vmlinux");
|
||||
block_count = 0;
|
||||
firstfill = 0;
|
||||
inbuf = ram = malloc(512);
|
||||
keof=0;
|
||||
tftp_init("vmlinux");
|
||||
block_bytes = 0;
|
||||
block_offset = 0;
|
||||
firstfill = 0;
|
||||
buffer = malloc(512);
|
||||
if (buffer == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = tftp_fetchone(ram);
|
||||
insize = rc;
|
||||
inptr = 1;
|
||||
return inbuf[0];
|
||||
keof=0;
|
||||
}
|
||||
|
||||
#endif // USE_TFTP
|
||||
static void fini_bytes(void)
|
||||
{
|
||||
free(buffer);
|
||||
buffer = 0;
|
||||
}
|
||||
|
||||
static byte_offset_t tftp_read_bytes(int cp, void *vdest, byte_offset_t count)
|
||||
{
|
||||
byte_offset_t bytes = 0;
|
||||
unsigned char *dest = vdest;
|
||||
if (keof)
|
||||
return -1;
|
||||
do {
|
||||
int length;
|
||||
if (block_bytes - block_offset == 0) {
|
||||
block_offset = 0;
|
||||
block_bytes = tftp_fetchone(buffer);
|
||||
}
|
||||
if (block_bytes <= 0) {
|
||||
keof = 1;
|
||||
return -1;
|
||||
}
|
||||
length = block_bytes - block_offset;
|
||||
if (length > count) {
|
||||
length = count;
|
||||
}
|
||||
|
||||
if (cp) {
|
||||
memcpy(dest, buffer, + block_offset, length);
|
||||
}
|
||||
block_offset += length;
|
||||
dest += length;
|
||||
} while (bytes < count);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static byte_offset_t skip_bytes(byte_offset_t count)
|
||||
{
|
||||
return tftp_read_bytes(0, 0, count);
|
||||
}
|
||||
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
|
||||
{
|
||||
return tftp_read_bytes(1, vdest, count);
|
||||
}
|
||||
|
||||
static struct stream tftp_stream __stream = {
|
||||
.init = init_bytes,
|
||||
.read = read_bytes,
|
||||
.skip = skip_bytes,
|
||||
.fini = fini_bytes,
|
||||
|
||||
};
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
#ifdef USE_TSUNAMI_TIGBUS_ROM
|
||||
|
||||
#include <printk.h>
|
||||
#include <stdlib.h>
|
||||
#include <subr.h>
|
||||
#include <stddef.h>
|
||||
#include <rom/fill_inbuf.h>
|
||||
#include <rom/read_bytes.h>
|
||||
|
||||
#include <arch/io.h>
|
||||
#include <northbridge/alpha/tsunami/core_tsunami.h>
|
||||
|
@ -13,12 +11,7 @@
|
|||
#define TIG_KERNEL_START 0x20000
|
||||
#endif
|
||||
|
||||
static unsigned long nvram;
|
||||
static int block_count;
|
||||
static int firstfill = 1;
|
||||
static unsigned char *ram;
|
||||
|
||||
#define K64 (64 * 1024)
|
||||
static unsigned long offset;
|
||||
|
||||
#define MAX_TIG_FLASH_SIZE (16*1024*1024)
|
||||
static void tsunami_flash_copy_from(void *addr, unsigned long offset, long len)
|
||||
|
@ -34,65 +27,49 @@ static void tsunami_flash_copy_from(void *addr, unsigned long offset, long len)
|
|||
}
|
||||
}
|
||||
|
||||
int fill_inbuf(void)
|
||||
static int init_bytes(void)
|
||||
{
|
||||
extern unsigned char *inbuf;
|
||||
extern unsigned int insize;
|
||||
extern unsigned int inptr;
|
||||
|
||||
if (firstfill) {
|
||||
block_count = 0;
|
||||
firstfill = 0;
|
||||
ram = malloc(K64);
|
||||
if (!ram) {
|
||||
printk_emerg("%6d:%s() - "
|
||||
"ram malloc failed\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
return 0;
|
||||
}
|
||||
offset = 0;
|
||||
printk_debug("%6d:%s() - TIG_KERNEL_START:0x%08x\n",
|
||||
__LINE__, __FUNCTION__,
|
||||
TIG_KERNEL_START);
|
||||
}
|
||||
static void fini_bytes(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
static byte_offset_t skip_bytes(byte_offset_t count)
|
||||
{
|
||||
unsigned long new_offset;
|
||||
byte_offset_t len;
|
||||
new_offset = offset + count;
|
||||
if (new_offset > MAX_TIG_FLASH_SIZE) {
|
||||
new_offset = MAX_TIG_FLASH_SIZE;
|
||||
}
|
||||
|
||||
if (block_count > 31) {
|
||||
printk_emerg("%6d:%s() - overflowed source buffer\n",
|
||||
__LINE__, __FUNCTION__);
|
||||
insize = 0;
|
||||
return (0);
|
||||
}
|
||||
if (!block_count) {
|
||||
nvram = TIG_KERNEL_START;
|
||||
printk_debug("%6d:%s() - ram buffer:0x%08x\n",
|
||||
__LINE__, __FUNCTION__, ram);
|
||||
printk_debug("%6d:%s() - TIG_KERNEL_START:0x%08x\n",
|
||||
__LINE__, __FUNCTION__,
|
||||
TIG_KERNEL_START);
|
||||
}
|
||||
|
||||
|
||||
tsunami_flash_copy_from(ram, nvram, K64);
|
||||
printk_debug("\n%6d:%s() - nvram:0x%lx block_count:%d\n",
|
||||
__LINE__, __FUNCTION__, nvram, block_count);
|
||||
|
||||
#if 0
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < K64; i+= 16) {
|
||||
printk_debug("%05x: %02x %02x %02x %02x %02x %02x %02x %02x "
|
||||
"%02x %02x %02x %02x %02x %02x %02x %02x\n",
|
||||
(block_count << 16)+i,
|
||||
ram[i+0], ram[i+1], ram[i+2], ram[i+3],
|
||||
ram[i+4], ram[i+5], ram[i+6], ram[i+7],
|
||||
ram[i+8], ram[i+9], ram[i+10], ram[i+11],
|
||||
ram[i+12], ram[i+13], ram[i+14],ram[i+15]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
nvram += K64;
|
||||
inbuf = ram;
|
||||
insize = K64;
|
||||
inptr = 1;
|
||||
post_code(0xd0 + block_count);
|
||||
block_count++;
|
||||
return inbuf[0];
|
||||
len = new_offset - offset;
|
||||
offset = new_offset;
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif /* USE_TSUNAMI_TIGBUS_ROM */
|
||||
static byte_offset_t read_bytes(void *vdest, byte_offset_t count)
|
||||
{
|
||||
long length;
|
||||
length = MAX_TIG_FLASH_SIZE - offset;
|
||||
if (count < 0)
|
||||
count = 0;
|
||||
if (count < length) {
|
||||
length = count;
|
||||
}
|
||||
tsunami_flash_copy_from(vdest, offset, length);
|
||||
offset += length;
|
||||
return length;
|
||||
}
|
||||
|
||||
|
||||
static struct stream tsunami_tigbus_rom_stream __stream = {
|
||||
.init = init_bytes,
|
||||
.read = read_bytes,
|
||||
.skip = skip_bytes,
|
||||
.fini = fini_bytes,
|
||||
|
||||
};
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
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;
|
||||
|
|
|
@ -15,7 +15,7 @@ void ich2_rtc_init(void)
|
|||
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_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);
|
||||
|
|
|
@ -41,17 +41,17 @@ def add_main_rule_dependency(new_dependency):
|
|||
# this is a tuple, object name, source it depends on,
|
||||
# and an optional rule (can be empty) for actually building
|
||||
# the object
|
||||
def addobject(object, sourcepath, rule, condition):
|
||||
objectrules.append([object, topify(sourcepath), rule, condition])
|
||||
def addobject(object, sourcepath, rule, condition, variable):
|
||||
objectrules.append([object, topify(sourcepath), rule, condition, variable])
|
||||
|
||||
# OK, let's face it, make sucks.
|
||||
# if you have a rule like this:
|
||||
# a.o: /some/long/path/a.c
|
||||
# make won't apply the .c.o rule. Toy!
|
||||
|
||||
def addobject_defaultrule(object, sourcepath, condition):
|
||||
def addobject_defaultrule(object, sourcepath, condition, variable):
|
||||
defaultrule = "\t $(CC) -c $(CFLAGS) -o $@ $<"
|
||||
addobject(object, sourcepath, defaultrule, condition)
|
||||
addobject(object, sourcepath, defaultrule, condition, variable)
|
||||
|
||||
# for all these functions, you need:
|
||||
# the dir that the Config file is in
|
||||
|
@ -136,7 +136,7 @@ def keyboard(dir, keyboard_name):
|
|||
if (debug):
|
||||
print "KEYBOARD"
|
||||
keyboard_dir = os.path.join(treetop, 'src', keyboard_name)
|
||||
addobject_defaultrule('keyboard.o', keyboard_dir,'')
|
||||
addobject_defaultrule('keyboard.o', keyboard_dir,'','OBJECTS')
|
||||
|
||||
def cpu(dir, cpu_name):
|
||||
common_command_action(dir, 'cpu', cpu_name)
|
||||
|
@ -165,7 +165,7 @@ def superio(dir, superio_name):
|
|||
# note that superio is w.r.t. treetop
|
||||
buildfullpath('superio', superio_name)
|
||||
dir = os.path.join(treetop, 'src', 'superio', superio_name)
|
||||
addobject_defaultrule('superio.o', dir,'')
|
||||
addobject_defaultrule('superio.o', dir,'','OBJECTS')
|
||||
|
||||
# commands are of the form:
|
||||
# superio_name [name=val]*
|
||||
|
@ -188,8 +188,8 @@ def nsuperio(dir, superio_commands):
|
|||
dir = os.path.join(treetop, 'src', 'superio', superio_name)
|
||||
object="superio_%s.o" % superio_decl_name
|
||||
superio_source = dir + "/superio.c"
|
||||
addobject_defaultrule(object, superio_source,'')
|
||||
addobject_defaultrule('nsuperio.o', "", '')
|
||||
addobject_defaultrule(object, superio_source,'','OBJECTS')
|
||||
addobject_defaultrule('nsuperio.o', "", '','OBJECTS')
|
||||
rest = m.group(2)
|
||||
superio_cmds = '';
|
||||
m = command_re.match(rest)
|
||||
|
@ -251,7 +251,15 @@ def object(dir, command):
|
|||
m = re.match("([^" + wspc + "]+)([" + wspc + "]([^" + wspc + "]*)|)", command)
|
||||
obj_name = m.group(1)
|
||||
condition = m.group(3)
|
||||
addobject_defaultrule(obj_name, dir, condition)
|
||||
addobject_defaultrule(obj_name, dir, condition,'OBJECTS')
|
||||
|
||||
def driver(dir, command):
|
||||
wspc = string.whitespace
|
||||
m = re.match("([^" + wspc + "]+)([" + wspc + "]([^" + wspc + "]*)|)", command)
|
||||
obj_name = m.group(1)
|
||||
condition = m.group(3)
|
||||
addobject_defaultrule(obj_name, dir, condition, 'DRIVERS')
|
||||
|
||||
|
||||
# for eventual user-defined rules.
|
||||
# pattern is name : deps ; rule
|
||||
|
@ -390,6 +398,7 @@ command_vals = {
|
|||
'pcibridge' : [], # vendor, bridgename
|
||||
'superio' : [], # vendor, superio name
|
||||
'object' : {}, # path/filename.[cS]
|
||||
'driver' : {}, # path/filename.[cS]
|
||||
'mainboardinit' : [], # set of files to include for mainboard init
|
||||
'config_files' : [], # set of files we built the makefile from
|
||||
'ldscripts' : [], # set of files we build the linker script from
|
||||
|
@ -408,6 +417,7 @@ command_actions = {
|
|||
'superio' : superio,
|
||||
'nsuperio' : nsuperio,
|
||||
'object' : object,
|
||||
'driver' : driver,
|
||||
'linux' : linux,
|
||||
'payload' : payload,
|
||||
'raminit' : raminit,
|
||||
|
@ -595,13 +605,15 @@ def writemakefile(path):
|
|||
# print out all the object dependencies
|
||||
# There is ALWAYS a crt0.o
|
||||
file.write("OBJECTS-1 := crt0.o\n")
|
||||
file.write("DRIVERS-1 :=\n")
|
||||
for i in range(len(objectrules)):
|
||||
obj_name = objectrules[i][0]
|
||||
obj_cond = objectrules[i][3]
|
||||
obj_var = objectrules[i][4]
|
||||
if not obj_cond :
|
||||
file.write("OBJECTS-1 += %s\n" % (obj_name))
|
||||
file.write("%s-1 += %s\n" % (obj_var, obj_name))
|
||||
else:
|
||||
file.write("OBJECTS-$(%s) += %s\n" % (obj_cond, obj_name))
|
||||
file.write("%s-$(%s) += %s\n" % (obj_var, obj_cond, obj_name))
|
||||
|
||||
# print out all ldscript.ld dependencies
|
||||
file.write("LDSUBSCRIPTS-1 := \n" )
|
||||
|
|
Loading…
Add table
Reference in a new issue