From 96bc60d84f949ce5985fb4f6f3a7e4d7137723c9 Mon Sep 17 00:00:00 2001 From: "Ronald G. Minnich" Date: Thu, 30 Nov 2000 22:06:43 +0000 Subject: [PATCH] Added support for 64-bit base address registers. --- romimages/RON_L440GX/Makefile | 1 + romimages/RON_L440GX_SCSI/Makefile | 235 +++++++++++++++++++++++++++++ src/lib/linuxpci.c | 1 + src/lib/newpci.c | 100 ++++++++++-- 4 files changed, 323 insertions(+), 14 deletions(-) create mode 100644 romimages/RON_L440GX_SCSI/Makefile diff --git a/romimages/RON_L440GX/Makefile b/romimages/RON_L440GX/Makefile index 46ca2eca27..90b45dfb11 100644 --- a/romimages/RON_L440GX/Makefile +++ b/romimages/RON_L440GX/Makefile @@ -11,6 +11,7 @@ CPUFLAGS += -DCMD_LINE='"ro root=/dev/hda1 console=ttyS0,115200 debug 3 single"' CPUFLAGS += -DPIIX4_DEVFN=0x90 CPUFLAGS += -DUPDATE_MICROCODE CPUFLAGS += -DCONFIGURE_L2_CACHE +#CPUFLAGS += -DDEBUG LINUX=$(TOP)/../linux-2.4.0-test6.l440gx diff --git a/romimages/RON_L440GX_SCSI/Makefile b/romimages/RON_L440GX_SCSI/Makefile new file mode 100644 index 0000000000..8f59d4228f --- /dev/null +++ b/romimages/RON_L440GX_SCSI/Makefile @@ -0,0 +1,235 @@ +CPUFLAGS=-DL440GX -Di686 -Di586 -DINTEL_BRIDGE_CONFIG -DPIIX4E_NVRAM +CPUFLAGS += -D__KERNEL__ +CPUFLAGS += -DINTEL_PPRO_MTRR -DPIIX4E_KEYBOARD +CPUFLAGS += -DSMP +#CPUFLAGS += -DHAVE_FRAMEBUFFER +CPUFLAGS += -DNEWPCI +CPUFLAGS += -DZKERNEL_START=0xfff40000 +CPUFLAGS += -DZKERNEL_MASK=0x3ed +CPUFLAGS += -DSERIAL_CONSOLE +CPUFLAGS += -DCMD_LINE='"ro root=/dev/sda1 console=ttyS0,115200 debug 3 single"' +CPUFLAGS += -DPIIX4_DEVFN=0x90 +CPUFLAGS += -DUPDATE_MICROCODE +CPUFLAGS += -DCONFIGURE_L2_CACHE +#CPUFLAGS += -DDEBUG + +LINUX=$(TOP)/../linux-2.4.0-test6.l440gx.scsi + +TOP=../.. +INCLUDES=-nostdinc -I $(TOP)/src/include +CFLAGS=$(INCLUDES) -O2 $(CPUFLAGS) -Ilinux/include -Wall + +OBJECTS=crt0.o hardwaremain.o linuxbiosmain.o +OBJECTS += mainboard.o mtrr.o subr.o fill_inbuf.o params.o +OBJECTS += southbridge.o northbridge.o +#OBJECTS += pci.o +OBJECTS += printk.o vsprintf.o +OBJECTS += newpci.o linuxpci.o +OBJECTS += cpuid.o +OBJECTS += serial_subr.o +OBJECTS += mpspec.o +OBJECTS += microcode.o +OBJECTS += keyboard.o +OBJECTS += l2_cache.o + +LINK = ld -T $(TOP)/src/mainboard/intel/l440gx/ldscript.ld -o $@ $(OBJECTS) +CC=cc $(CFLAGS) +CCASM=cc -I$(TOP)/chip/intel $(CFLAGS) + +all: romimage +floppy: all + mcopy -o romimage a: +# here's the problem: we shouldn't assume we come up with more than +# 64K of FLASH up. SO we need a working linuxbios at the tail, and it will +# enable all flash and then gunzip the linuxbios. As a result, +# we need the vmlinux.bin.gz padded out and then cat the linuxbios.rom +# at then end. We always copy it to /tmp so that a waiting root shell +# can put it on the floppy (see ROOTDOIT) +romimage: linuxbios.rom vmlinux.bin.gz.block + cat vmlinux.bin.gz.block linuxbios.rom > romimage + cp romimage /tmp + +linuxbios.rom: linuxbios.strip mkrom + ./mkrom -s 64 -f -o linuxbios.rom linuxbios.strip + +linuxbios.strip: linuxbios + objcopy -O binary -R .note -R .comment -S linuxbios linuxbios.strip + +linuxbios: $(OBJECTS) vmlinux.bin.gz + @rm -f biosobject + $(LINK) + nm -n linuxbios > linuxbios.map + +# crt0 actually includes .inc files. +# For self-documenting purposes, we put the FULL PATH of the +# .inc files (relative to $TOP/src) in crt0.S. +# So, for example, earlymtrr.inc is included as cpu/p6/earlymtrr.inc +# To make this work, add the extra -I $(TOP)/src here. +crt0.s: $(TOP)/src/mainboard/intel/l440gx/crt0.S + $(CCASM) -I $(TOP)/src -E $< > crt0.s + +crt0.o : crt0.s + $(CCASM) -c crt0.s + +mkrom: $(TOP)/mkrom/mkrom.c + cc -o mkrom $< + +linuxbiosmain.o: $(TOP)/src/lib/linuxbiosmain.c + cc $(CFLAGS) -c $< + +mainboard.o: $(TOP)/src/mainboard/intel/l440gx/mainboard.c + cc $(CFLAGS) -c $< + +fill_inbuf.o: $(TOP)/src/lib/fill_inbuf.c + cc $(CFLAGS) -c $< + +params.o: $(TOP)/src/lib/params.c + cc $(CFLAGS) $(LINUXINCLUDE) -c $< + +hardwaremain.o: $(TOP)/src/lib/hardwaremain.c + cc $(CFLAGS) -c $< + +southbridge.o: $(TOP)/src/southbridge/intel/piix4e/southbridge.c + cc $(CFLAGS) -c $< + +northbridge.o: $(TOP)/src/northbridge/intel/440gx/northbridge.c + cc $(CFLAGS) -c $< + +#superio.o: $(TOP)/src/superio/intel/950/superio.c +# cc $(CFLAGS) -c $< + +pci.o: $(TOP)/src/lib/pci.c + cc $(CFLAGS) -c $< + + +mtrr.o: $(TOP)/src/cpu/p6/mtrr.c + cc $(CFLAGS) -c $< + +subr.o: $(TOP)/src/lib/subr.c + cc $(CFLAGS) -c $< + +keyboard.o: $(TOP)/src/pc80/keyboard.c + cc $(CFLAGS) -c $< + +cpuid.o: $(TOP)/src/cpu/p5/cpuid.c + cc $(CFLAGS) -c $< + +mpspec.o: $(TOP)/src/cpu/p6/mpspec.c + $(CC) $(CFLAGS) -c $< + +microcode.o: $(TOP)/src/cpu/p6/microcode.c + $(CC) $(CFLAGS) -c $< + +l2_cache.o: $(TOP)/src/cpu/p6/l2_cache.c + $(CC) $(CFLAGS) -c $< + +serial_subr.o: $(TOP)/src/lib/serial_subr.c + cc $(CFLAGS) -c $< + +printk.o: $(TOP)/src/lib/printk.c + cc $(CFLAGS) -c $< + +vsprintf.o: $(TOP)/src/lib/vsprintf.c + cc $(CFLAGS) -c $< + +newpci.o: $(TOP)/src/lib/newpci.c + cc $(CFLAGS) -c $< + +linuxpci.o: $(TOP)/src/lib/linuxpci.c + cc $(CFLAGS) -c $< + +vmlinux.bin.gz.block: vmlinux.bin.gz + dd conv=sync bs=640k if=vmlinux.bin.gz of=vmlinux.bin.gz.block +vmlinux.bin.gz: vmlinux.bin + gzip -f -3 vmlinux.bin + +vmlinux.bin: $(LINUX)/vmlinux + objcopy -O binary -R .note -R .comment -S $< vmlinux.bin + +alltags: + gctags ../inflate/*.c ../../lib/*.c ../../chip/intel/*.c + etags ../inflate/*.c ../../lib/*.c ../../chip/intel/*.c + + +clean:: + rm -f linuxbios.* vmlinux.* *.o mkrom xa? *~ linuxbios romimage crt0.s + rm -f a.out *.s *.l + rm -f TAGS tags + rm -f docipl + + + + + + +# here begins stupid stuff for the phlash program. It's ugly. + +#PHLASH_BASE_NAME=p11-0105 +PHLASH_BASE_NAME=p11-0102 +#PHLASH_BASE_NAME=p12-0115 +#PHLASH_BASE_NAME=p13-0125 + +phlash: vmlinux.bin.gz linuxbios.rom headers + rm -f xa? + split -b 64k vmlinux.bin.gz +# Now just touch them if we have a really +# small kernel! + touch xaa xab xac xad xae xaf xag xah +# this if starting at bank 4, and proceeding on. Unused banks are dups +# intel nvram is odd all of the banks are byte swapped + cat $(PHLASH_BASE_NAME).bi1.header xaa > $(PHLASH_BASE_NAME).bi1 + cat $(PHLASH_BASE_NAME).bi3.header xab > $(PHLASH_BASE_NAME).bi3 + cat $(PHLASH_BASE_NAME).bi2.header xac > $(PHLASH_BASE_NAME).bi2 + cat $(PHLASH_BASE_NAME).bi4.header xad > $(PHLASH_BASE_NAME).bi4 + cat $(PHLASH_BASE_NAME).bi7.header xae > $(PHLASH_BASE_NAME).bi7 + cat $(PHLASH_BASE_NAME).bi6.header xaf > $(PHLASH_BASE_NAME).bi6 + cat $(PHLASH_BASE_NAME).bi9.header xag > $(PHLASH_BASE_NAME).bi9 + cat $(PHLASH_BASE_NAME).bi8.header xah > $(PHLASH_BASE_NAME).bi8 + cat $(PHLASH_BASE_NAME).bia.header linuxbios.rom > $(PHLASH_BASE_NAME).bia + # Part o & 5 seem not to be written reliably for some reason... + cat $(PHLASH_BASE_NAME).bio.header /dev/null > $(PHLASH_BASE_NAME).bio + cat $(PHLASH_BASE_NAME).bi5.header /dev/null > $(PHLASH_BASE_NAME).bi5 + sh -x $(TOP)/src/mainboard/intel/l440gx/BUILD_PHLASH_FILES $(PHLASH_BASE_NAME) + +headers: \ + $(PHLASH_BASE_NAME).bi1.header \ + $(PHLASH_BASE_NAME).bi2.header \ + $(PHLASH_BASE_NAME).bi3.header \ + $(PHLASH_BASE_NAME).bi4.header \ + $(PHLASH_BASE_NAME).bi5.header \ + $(PHLASH_BASE_NAME).bi6.header \ + $(PHLASH_BASE_NAME).bi7.header \ + $(PHLASH_BASE_NAME).bi8.header \ + $(PHLASH_BASE_NAME).bi9.header \ + $(PHLASH_BASE_NAME).bia.header \ + $(PHLASH_BASE_NAME).bio.header + +# This builds the headers from the intel flash disk. +# we are not distributing this disk; you need to get it. +BUILDHEADER=dd if=$< of=$@ bs=1 count=160 + +$(PHLASH_BASE_NAME).bi1.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi1 + $(BUILDHEADER) +$(PHLASH_BASE_NAME).bi2.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi2 + $(BUILDHEADER) +$(PHLASH_BASE_NAME).bi3.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi3 + $(BUILDHEADER) +$(PHLASH_BASE_NAME).bi4.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi4 + $(BUILDHEADER) +$(PHLASH_BASE_NAME).bi5.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi5 + $(BUILDHEADER) +$(PHLASH_BASE_NAME).bi6.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi6 + $(BUILDHEADER) +$(PHLASH_BASE_NAME).bi7.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi7 + $(BUILDHEADER) +$(PHLASH_BASE_NAME).bi8.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi8 + $(BUILDHEADER) +$(PHLASH_BASE_NAME).bi9.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bi9 + $(BUILDHEADER) +$(PHLASH_BASE_NAME).bia.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bia + $(BUILDHEADER) +$(PHLASH_BASE_NAME).bio.header: $(TOP)/../intel_flash_disk/$(PHLASH_BASE_NAME).bio + $(BUILDHEADER) + + + diff --git a/src/lib/linuxpci.c b/src/lib/linuxpci.c index d315acf818..597c71f77b 100644 --- a/src/lib/linuxpci.c +++ b/src/lib/linuxpci.c @@ -179,6 +179,7 @@ void pci_read_bases(struct pci_dev *dev, unsigned int howmany) addr &= (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK); if (addr == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) { + DBG("reg %d is 64-bit\n", reg); /* this is a 64-bit memory base address */ reg++; pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + (reg << 2), &addr); diff --git a/src/lib/newpci.c b/src/lib/newpci.c index 8f27300de6..0cd53b6f83 100644 --- a/src/lib/newpci.c +++ b/src/lib/newpci.c @@ -268,17 +268,31 @@ static const struct pci_ops *pci_check_direct(void) int pci_read_config_byte(struct pci_dev *dev, u8 where, u8 * val) { - return conf->read_byte(dev->bus->number, dev->devfn, where, val); + int res; + res = conf->read_byte(dev->bus->number, dev->devfn, where, val); + DBG("Read config byte bus %d,devfn 0x%x,reg 0x%x,val 0x%x,res 0x%x\n", + dev->bus->number, dev->devfn, where, *val, res); + return res; + + } int pci_read_config_word(struct pci_dev *dev, u8 where, u16 * val) { - return conf->read_word(dev->bus->number, dev->devfn, where, val); + int res; + res = conf->read_word(dev->bus->number, dev->devfn, where, val); + DBG("Read config word bus %d,devfn 0x%x,reg 0x%x,val 0x%x,res 0x%x\n", + dev->bus->number, dev->devfn, where, *val, res); + return res; } int pci_read_config_dword(struct pci_dev *dev, u8 where, u32 * val) { - return conf->read_dword(dev->bus->number, dev->devfn, where, val); + int res; + res = conf->read_dword(dev->bus->number, dev->devfn, where, val); + DBG("Read config dword bus %d,devfn 0x%x,reg 0x%x,val 0x%x,res 0x%x\n", + dev->bus->number, dev->devfn, where, *val, res); + return res; } int pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val) @@ -290,7 +304,7 @@ int pci_write_config_byte(struct pci_dev *dev, u8 where, u8 val) int pci_write_config_word(struct pci_dev *dev, u8 where, u16 val) { - DBG("Write config byte bus %d, devfn 0x%x, reg 0x%x, val 0x%x\n", + DBG("Write config word bus %d, devfn 0x%x, reg 0x%x, val 0x%x\n", dev->bus->number, dev->devfn, where, val); return conf->write_word(dev->bus->number, dev->devfn, where, val); @@ -298,24 +312,38 @@ int pci_write_config_word(struct pci_dev *dev, u8 where, u16 val) int pci_write_config_dword(struct pci_dev *dev, u8 where, u32 val) { - DBG("Write config byte bus %d, devfn 0x%x, reg 0x%x, val 0x%x\n", + DBG("Write config dword bus %d, devfn 0x%x, reg 0x%x, val 0x%x\n", dev->bus->number, dev->devfn, where, val); return conf->write_dword(dev->bus->number, dev->devfn, where, val); } int pcibios_read_config_byte(unsigned char bus, unsigned char devfn, u8 where, u8 * val) { - return conf->read_byte(bus, devfn, where, val); + int res; + res = conf->read_byte(bus, devfn, where, val); + DBG("Read config byte bus %d,devfn 0x%x,reg 0x%x,val 0x%x,res 0x%x\n", + bus, devfn, where, *val, res); + return res; } int pcibios_read_config_word(unsigned char bus, unsigned char devfn, u8 where, u16 * val) { - return conf->read_word(bus, devfn, where, val); + int res; + res = conf->read_word(bus, devfn, where, val); + DBG("Read config word bus %d,devfn 0x%x,reg 0x%x,val 0x%x,res 0x%x\n", + bus, devfn, where, *val, res); + return res; + } int pcibios_read_config_dword(unsigned char bus, unsigned char devfn, u8 where, u32 * val) { - return conf->read_dword(bus, devfn, where, val); + int res; + res = conf->read_dword(bus, devfn, where, val); + DBG("Read config dword bus %d,devfn 0x%x,reg 0x%x,val 0x%x,res 0x%x\n", + bus, devfn, where, *val, res); + return res; + } int pcibios_write_config_byte(unsigned char bus, unsigned char devfn, u8 where, u8 val) @@ -424,7 +452,7 @@ void compute_allocate_io(struct pci_bus *bus) unsigned long io_base; io_base = bus->iobase; - DBG("compute_allocate_mem: base 0x%lx\n", bus->iobase); + DBG("compute_allocate_io: base 0x%lx\n", bus->iobase); /* First, walk all the bridges. When you return, grow the limit of the current bus since sub-busses need IO rounded to 4096 */ @@ -493,11 +521,30 @@ void compute_allocate_mem(struct pci_bus *bus) unsigned long size = curdev->size[i]; unsigned long memorysize = size & (PCI_BASE_ADDRESS_MEM_MASK); unsigned long type = size & (~PCI_BASE_ADDRESS_MEM_MASK); - - if (!memorysize) + if (!memorysize) { continue; + } + + if (type & PCI_BASE_ADDRESS_SPACE_IO) { + continue; + } - if (type == 0) { + // we don't support the 1M type + if (type & PCI_BASE_ADDRESS_MEM_TYPE_1M) { + continue; + } + + // if it's prefetch type, continue; + if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) { + continue; + } + + // now mask out all but the 32 or 64 bits + type &= PCI_BASE_ADDRESS_MEM_TYPE_MASK; + + // I'm pretty sure this test is not needed, but ... + if ((type == PCI_BASE_ADDRESS_MEM_TYPE_32) || + (type == PCI_BASE_ADDRESS_MEM_TYPE_64)) { /* this is normal memory space */ unsigned long regmem; @@ -512,6 +559,10 @@ void compute_allocate_mem(struct pci_bus *bus) DBG("-->set base to 0x%lx\n", mem_base); mem_base += regmem; curdev->command |= PCI_COMMAND_MEMORY; + // for 64-bit BARs, the odd ones don't count + if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) + continue; + } } } @@ -553,8 +604,26 @@ void compute_allocate_prefmem(struct pci_bus *bus) if (!memorysize) continue; - if (type & PCI_BASE_ADDRESS_MEM_PREFETCH) { - /* this is a prefetchable memory area */ + if (type & PCI_BASE_ADDRESS_SPACE_IO) { + continue; + } + + // we don't support the 1M type + if (type & PCI_BASE_ADDRESS_MEM_TYPE_1M) { + printk(__FUNCTION__ ": 1M memory not supported\n"); + continue; + } + + // if it's not a prefetch type, continue; + if (! (type & PCI_BASE_ADDRESS_MEM_PREFETCH)) + continue; + // this should be a function some day ... comon code with + // the non-prefetch allocate + // now mask out all but the 32 or 64 bit type info + type &= PCI_BASE_ADDRESS_MEM_TYPE_MASK; + // if all these names confuse you, they confuse me too! + if ((type == PCI_BASE_ADDRESS_MEM_TYPE_32) || + (type == PCI_BASE_ADDRESS_MEM_TYPE_64)) { unsigned long regmem; /* PCI BUS Spec suggests that the memory address should be @@ -568,6 +637,9 @@ void compute_allocate_prefmem(struct pci_bus *bus) DBG("-->set base to 0x%lx\n", prefmem_base); prefmem_base += regmem; curdev->command |= PCI_COMMAND_MEMORY; + // for 64-bit BARs, the odd ones don't count + if (type == PCI_BASE_ADDRESS_MEM_TYPE_64) + continue; } } }