diff options
Diffstat (limited to 'src')
28 files changed, 1527 insertions, 1062 deletions
diff --git a/src/arch/i386/boot/linuxbios_table.c b/src/arch/i386/boot/linuxbios_table.c index 5b7431479b..0866639f1e 100644 --- a/src/arch/i386/boot/linuxbios_table.c +++ b/src/arch/i386/boot/linuxbios_table.c @@ -1,5 +1,4 @@ #include <console/console.h> -#include <mem.h> #include <ip_checksum.h> #include <boot/linuxbios_tables.h> #include "linuxbios_table.h" @@ -8,7 +7,6 @@ #include <device/device.h> #include <stdlib.h> - struct lb_header *lb_table_init(unsigned long addr) { struct lb_header *header; @@ -130,11 +128,8 @@ void lb_strings(struct lb_header *header) } -/* Some version of gcc have problems with 64 bit types so - * take an unsigned long instead of a uint64_t for now. - */ void lb_memory_range(struct lb_memory *mem, - uint32_t type, unsigned long start, unsigned long size) + uint32_t type, uint64_t start, uint64_t size) { int entries; entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); @@ -144,19 +139,6 @@ void lb_memory_range(struct lb_memory *mem, mem->size += sizeof(mem->map[0]); } -static void lb_memory_rangek(struct lb_memory *mem, - uint32_t type, unsigned long startk, unsigned long endk) -{ - int entries; - entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); - mem->map[entries].start = startk; - mem->map[entries].start <<= 10; - mem->map[entries].size = endk - startk; - mem->map[entries].size <<= 10; - mem->map[entries].type = type; - mem->size += sizeof(mem->map[0]); -} - static void lb_reserve_table_memory(struct lb_header *head) { struct lb_record *last_rec; @@ -189,7 +171,6 @@ static void lb_reserve_table_memory(struct lb_header *head) } } - unsigned long lb_table_fini(struct lb_header *head) { struct lb_record *rec, *first_rec; @@ -207,6 +188,112 @@ unsigned long lb_table_fini(struct lb_header *head) return (unsigned long)rec; } +static void lb_cleanup_memory_ranges(struct lb_memory *mem) +{ + int entries; + int i, j; + entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); + + /* Sort the lb memory ranges */ + for(i = 0; i < entries; i++) { + for(j = i; j < entries; j++) { + if (mem->map[j].start < mem->map[i].start) { + struct lb_memory_range tmp; + tmp = mem->map[i]; + mem->map[i] = mem->map[j]; + mem->map[j] = tmp; + } + } + } + + /* Merge adjacent entries */ + for(i = 0; (i + 1) < entries; i++) { + uint64_t start, end, nstart, nend; + if (mem->map[i].type != mem->map[i + 1].type) { + continue; + } + start = mem->map[i].start; + end = start + mem->map[i].size; + nstart = mem->map[i + 1].start; + nend = nstart + mem->map[i + 1].size; + if ((start <= nstart) && (end > nstart)) { + if (start > nstart) { + start = nstart; + } + if (end < nend) { + end = nend; + } + /* Record the new region size */ + mem->map[i].start = start; + mem->map[i].size = end - start; + + /* Delete the entry I have merged with */ + memmove(&mem->map[i + 1], &mem->map[i + 2], + ((entries - i - 2) * sizeof(mem->map[0]))); + mem->size -= sizeof(mem->map[0]); + entries -= 1; + /* See if I can merge with the next entry as well */ + i -= 1; + } + } +} + +static void lb_remove_memory_range(struct lb_memory *mem, + uint64_t start, uint64_t size) +{ + uint64_t end; + int entries; + int i; + + end = start + size; + entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); + + /* Remove a reserved area from the memory map */ + for(i = 0; i < entries; i++) { + uint64_t map_start = mem->map[i].start; + uint64_t map_end = map_start + mem->map[i].size; + if ((start <= map_start) && (end >= map_end)) { + /* Remove the completely covered range */ + memmove(&mem->map[i], &mem->map[i + 1], + ((entries - i - 1) * sizeof(mem->map[0]))); + mem->size -= sizeof(mem->map[0]); + entries -= 1; + /* Since the index will disappear revisit what will appear here */ + i -= 1; + } + else if ((start > map_start) && (end < map_end)) { + /* Split the memory range */ + memmove(&mem->map[i + 1], &mem->map[i], + ((entries - i) * sizeof(mem->map[0]))); + mem->size += sizeof(mem->map[0]); + entries += 1; + /* Update the first map entry */ + mem->map[i].size = start - map_start; + /* Update the second map entry */ + mem->map[i + 1].start = end; + mem->map[i + 1].size = map_end - end; + /* Don't bother with this map entry again */ + i += 1; + } + else if ((start <= map_start) && (end > map_start)) { + /* Shrink the start of the memory range */ + mem->map[i].start = end; + mem->map[i].size = map_end - end; + } + else if ((start < map_end) && (start > map_start)) { + /* Shrink the end of the memory range */ + mem->map[i].size = start - map_start; + } + } +} + +static void lb_add_memory_range(struct lb_memory *mem, + uint32_t type, uint64_t start, uint64_t size) +{ + lb_remove_memory_range(mem, start, size); + lb_memory_range(mem, type, start, size); + lb_cleanup_memory_ranges(mem); +} /* Routines to extract part so the linuxBIOS table or * information from the linuxBIOS table after we have written it. @@ -219,61 +306,28 @@ struct lb_memory *get_lb_mem(void) return mem_ranges; } -struct mem_range *sizeram(void) +static struct lb_memory *build_lb_mem(struct lb_header *head) { - struct mem_range *mem, *rmem; + struct lb_memory *mem; struct device *dev; - unsigned int count; - count = 0; - for(dev = all_devices; dev; dev = dev->next) { - struct resource *res, *last; - last = &dev->resource[dev->resources]; - for(res = &dev->resource[0]; res < last; res++) { - if ((res->flags & IORESOURCE_MEM) && - (res->flags & IORESOURCE_CACHEABLE)) - { - count++; - } - } - } - rmem = mem = malloc(sizeof(*mem) * (count + 1)); + + /* Record where the lb memory ranges will live */ + mem = lb_memory(head); + mem_ranges = mem; + + /* Build the raw table of memory */ for(dev = all_devices; dev; dev = dev->next) { struct resource *res, *last; last = &dev->resource[dev->resources]; for(res = &dev->resource[0]; res < last; res++) { - if ((res->flags & IORESOURCE_MEM) && - (res->flags & IORESOURCE_CACHEABLE)) - { - mem->basek = res->base >> 10; - mem->sizek = res->size >> 10; - mem++; + if (!(res->flags & IORESOURCE_MEM) || + !(res->flags & IORESOURCE_CACHEABLE)) { + continue; } + lb_memory_range(mem, LB_MEM_RAM, res->base, res->size); } } - mem->basek = 0; - mem->sizek = 0; -#if 0 - for(mem = rmem; mem->sizek; mem++) { - printk_debug("basek: %lu sizek: %lu\n", - mem->basek, mem->sizek); - } -#endif - return rmem; -} - -static struct mem_range *get_ramsize(void) -{ - struct mem_range *mem = 0; - if (!mem) { - mem = sizeram(); - } - if (!mem) { - printk_emerg("No memory size information!\n"); - for(;;) { - /* Ensure this loop is not optimized away */ - asm volatile("":/* outputs */:/*inputs */ :"memory"); - } - } + lb_cleanup_memory_ranges(mem); return mem; } @@ -282,51 +336,38 @@ unsigned long write_linuxbios_table( unsigned long rom_table_startk, unsigned long rom_table_endk) { unsigned long table_size; - struct mem_range *ram, *ramp; struct lb_header *head; struct lb_memory *mem; - struct lb_record *rec_dest, *rec_src; - ram = get_ramsize(); head = lb_table_init(low_table_end); low_table_end = (unsigned long)head; -#if HAVE_OPTION_TABLE == 1 - /* Write the option config table... */ - rec_dest = lb_new_record(head); - rec_src = (struct lb_record *)&option_table; - memcpy(rec_dest, rec_src, rec_src->size); -#endif - mem = lb_memory(head); - mem_ranges = mem; - /* I assume there is always ram at address 0 */ - /* Reserve our tables in low memory */ + if (HAVE_OPTION_TABLE == 1) { + struct lb_record *rec_dest, *rec_src; + /* Write the option config table... */ + rec_dest = lb_new_record(head); + rec_src = (struct lb_record *)&option_table; + memcpy(rec_dest, rec_src, rec_src->size); + } + /* Record where RAM is located */ + mem = build_lb_mem(head); + + /* Find the current mptable size */ table_size = (low_table_end - low_table_start); - lb_memory_range(mem, LB_MEM_TABLE, 0, table_size); - lb_memory_range(mem, LB_MEM_RAM, table_size, (ram[0].sizek << 10) - table_size); - /* Reserving pci memory mapped space will keep the kernel from booting seeing - * any pci resources. + + /* Record the mptable and the the lb_table (This will be adjusted later) */ + lb_add_memory_range(mem, LB_MEM_TABLE, + low_table_start, table_size); + + /* Record the pirq table */ + lb_add_memory_range(mem, LB_MEM_TABLE, + rom_table_startk << 10, (rom_table_endk - rom_table_startk) << 10); + + /* Note: + * I assume that there is always memory at immediately after + * the low_table_end. This means that after I setup the linuxbios table. + * I can trivially fixup the reserved memory ranges to hold the correct + * size of the linuxbios table. */ - for(ramp = &ram[1]; ramp->sizek; ramp++) { - unsigned long startk, endk; - startk = ramp->basek; - endk = startk + ramp->sizek; - if ((startk < rom_table_startk) && (endk > rom_table_startk)) { - lb_memory_rangek(mem, LB_MEM_RAM, startk, rom_table_startk); - startk = rom_table_startk; - } - if ((startk == rom_table_startk) && (endk > startk)) { - unsigned long tend; - tend = rom_table_endk; - if (tend > endk) { - tend = endk; - } - lb_memory_rangek(mem, LB_MEM_TABLE, rom_table_startk, tend); - startk = tend; - } - if (endk > startk) { - lb_memory_rangek(mem, LB_MEM_RAM, startk, endk); - } - } /* Record our motheboard */ lb_mainboard(head); diff --git a/src/arch/i386/boot/linuxbios_table.h b/src/arch/i386/boot/linuxbios_table.h index d15e1c722a..41ac37a8de 100644 --- a/src/arch/i386/boot/linuxbios_table.h +++ b/src/arch/i386/boot/linuxbios_table.h @@ -15,7 +15,7 @@ struct lb_record *lb_next_record(struct lb_record *rec); struct lb_record *lb_new_record(struct lb_header *header); struct lb_memory *lb_memory(struct lb_header *header); void lb_memory_range(struct lb_memory *mem, - uint32_t type, unsigned long startk, unsigned long sizek); + uint32_t type, uint64_t start, uint64_t size); struct lb_mainboard *lb_mainboard(struct lb_header *header); unsigned long lb_table_fini(struct lb_header *header); diff --git a/src/arch/ppc/boot/linuxbios_table.c b/src/arch/ppc/boot/linuxbios_table.c index 2b37e877e5..0866639f1e 100644 --- a/src/arch/ppc/boot/linuxbios_table.c +++ b/src/arch/ppc/boot/linuxbios_table.c @@ -1,11 +1,11 @@ #include <console/console.h> -#include <mem.h> #include <ip_checksum.h> #include <boot/linuxbios_tables.h> #include "linuxbios_table.h" #include <string.h> #include <version.h> - +#include <device/device.h> +#include <stdlib.h> struct lb_header *lb_table_init(unsigned long addr) { @@ -128,11 +128,8 @@ void lb_strings(struct lb_header *header) } -/* Some version of gcc have problems with 64 bit types so - * take an unsigned long instead of a uint64_t for now. - */ void lb_memory_range(struct lb_memory *mem, - uint32_t type, unsigned long start, unsigned long size) + uint32_t type, uint64_t start, uint64_t size) { int entries; entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); @@ -142,19 +139,6 @@ void lb_memory_range(struct lb_memory *mem, mem->size += sizeof(mem->map[0]); } -static void lb_memory_rangek(struct lb_memory *mem, - uint32_t type, unsigned long startk, unsigned long endk) -{ - int entries; - entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); - mem->map[entries].start = startk; - mem->map[entries].start <<= 10; - mem->map[entries].size = endk - startk; - mem->map[entries].size <<= 10; - mem->map[entries].type = type; - mem->size += sizeof(mem->map[0]); -} - static void lb_reserve_table_memory(struct lb_header *head) { struct lb_record *last_rec; @@ -187,7 +171,6 @@ static void lb_reserve_table_memory(struct lb_header *head) } } - unsigned long lb_table_fini(struct lb_header *head) { struct lb_record *rec, *first_rec; @@ -205,6 +188,112 @@ unsigned long lb_table_fini(struct lb_header *head) return (unsigned long)rec; } +static void lb_cleanup_memory_ranges(struct lb_memory *mem) +{ + int entries; + int i, j; + entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); + + /* Sort the lb memory ranges */ + for(i = 0; i < entries; i++) { + for(j = i; j < entries; j++) { + if (mem->map[j].start < mem->map[i].start) { + struct lb_memory_range tmp; + tmp = mem->map[i]; + mem->map[i] = mem->map[j]; + mem->map[j] = tmp; + } + } + } + + /* Merge adjacent entries */ + for(i = 0; (i + 1) < entries; i++) { + uint64_t start, end, nstart, nend; + if (mem->map[i].type != mem->map[i + 1].type) { + continue; + } + start = mem->map[i].start; + end = start + mem->map[i].size; + nstart = mem->map[i + 1].start; + nend = nstart + mem->map[i + 1].size; + if ((start <= nstart) && (end > nstart)) { + if (start > nstart) { + start = nstart; + } + if (end < nend) { + end = nend; + } + /* Record the new region size */ + mem->map[i].start = start; + mem->map[i].size = end - start; + + /* Delete the entry I have merged with */ + memmove(&mem->map[i + 1], &mem->map[i + 2], + ((entries - i - 2) * sizeof(mem->map[0]))); + mem->size -= sizeof(mem->map[0]); + entries -= 1; + /* See if I can merge with the next entry as well */ + i -= 1; + } + } +} + +static void lb_remove_memory_range(struct lb_memory *mem, + uint64_t start, uint64_t size) +{ + uint64_t end; + int entries; + int i; + + end = start + size; + entries = (mem->size - sizeof(*mem))/sizeof(mem->map[0]); + + /* Remove a reserved area from the memory map */ + for(i = 0; i < entries; i++) { + uint64_t map_start = mem->map[i].start; + uint64_t map_end = map_start + mem->map[i].size; + if ((start <= map_start) && (end >= map_end)) { + /* Remove the completely covered range */ + memmove(&mem->map[i], &mem->map[i + 1], + ((entries - i - 1) * sizeof(mem->map[0]))); + mem->size -= sizeof(mem->map[0]); + entries -= 1; + /* Since the index will disappear revisit what will appear here */ + i -= 1; + } + else if ((start > map_start) && (end < map_end)) { + /* Split the memory range */ + memmove(&mem->map[i + 1], &mem->map[i], + ((entries - i) * sizeof(mem->map[0]))); + mem->size += sizeof(mem->map[0]); + entries += 1; + /* Update the first map entry */ + mem->map[i].size = start - map_start; + /* Update the second map entry */ + mem->map[i + 1].start = end; + mem->map[i + 1].size = map_end - end; + /* Don't bother with this map entry again */ + i += 1; + } + else if ((start <= map_start) && (end > map_start)) { + /* Shrink the start of the memory range */ + mem->map[i].start = end; + mem->map[i].size = map_end - end; + } + else if ((start < map_end) && (start > map_start)) { + /* Shrink the end of the memory range */ + mem->map[i].size = start - map_start; + } + } +} + +static void lb_add_memory_range(struct lb_memory *mem, + uint32_t type, uint64_t start, uint64_t size) +{ + lb_remove_memory_range(mem, start, size); + lb_memory_range(mem, type, start, size); + lb_cleanup_memory_ranges(mem); +} /* Routines to extract part so the linuxBIOS table or * information from the linuxBIOS table after we have written it. @@ -217,58 +306,68 @@ struct lb_memory *get_lb_mem(void) return mem_ranges; } +static struct lb_memory *build_lb_mem(struct lb_header *head) +{ + struct lb_memory *mem; + struct device *dev; + + /* Record where the lb memory ranges will live */ + mem = lb_memory(head); + mem_ranges = mem; + + /* Build the raw table of memory */ + for(dev = all_devices; dev; dev = dev->next) { + struct resource *res, *last; + last = &dev->resource[dev->resources]; + for(res = &dev->resource[0]; res < last; res++) { + if (!(res->flags & IORESOURCE_MEM) || + !(res->flags & IORESOURCE_CACHEABLE)) { + continue; + } + lb_memory_range(mem, LB_MEM_RAM, res->base, res->size); + } + } + lb_cleanup_memory_ranges(mem); + return mem; +} + unsigned long write_linuxbios_table( - struct mem_range *ram, unsigned long low_table_start, unsigned long low_table_end, unsigned long rom_table_startk, unsigned long rom_table_endk) { unsigned long table_size; - struct mem_range *ramp; struct lb_header *head; struct lb_memory *mem; -#if HAVE_OPTION_TABLE == 1 - struct lb_record *rec_dest, *rec_src; -#endif head = lb_table_init(low_table_end); low_table_end = (unsigned long)head; -#if HAVE_OPTION_TABLE == 1 - /* Write the option config table... */ - rec_dest = lb_new_record(head); - rec_src = (struct lb_record *)&option_table; - memcpy(rec_dest, rec_src, rec_src->size); -#endif - mem = lb_memory(head); - mem_ranges = mem; - /* I assume there is always ram at address 0 */ - /* Reserve our tables in low memory */ + if (HAVE_OPTION_TABLE == 1) { + struct lb_record *rec_dest, *rec_src; + /* Write the option config table... */ + rec_dest = lb_new_record(head); + rec_src = (struct lb_record *)&option_table; + memcpy(rec_dest, rec_src, rec_src->size); + } + /* Record where RAM is located */ + mem = build_lb_mem(head); + + /* Find the current mptable size */ table_size = (low_table_end - low_table_start); - lb_memory_range(mem, LB_MEM_TABLE, 0, table_size); - lb_memory_range(mem, LB_MEM_RAM, table_size, (ram[0].sizek << 10) - table_size); - /* Reserving pci memory mapped space will keep the kernel from booting seeing - * any pci resources. + + /* Record the mptable and the the lb_table (This will be adjusted later) */ + lb_add_memory_range(mem, LB_MEM_TABLE, + low_table_start, table_size); + + /* Record the pirq table */ + lb_add_memory_range(mem, LB_MEM_TABLE, + rom_table_startk << 10, (rom_table_endk - rom_table_startk) << 10); + + /* Note: + * I assume that there is always memory at immediately after + * the low_table_end. This means that after I setup the linuxbios table. + * I can trivially fixup the reserved memory ranges to hold the correct + * size of the linuxbios table. */ - for(ramp = &ram[1]; ramp->sizek; ramp++) { - unsigned long startk, endk; - startk = ramp->basek; - endk = startk + ramp->sizek; - if ((startk < rom_table_startk) && (endk > rom_table_startk)) { - lb_memory_rangek(mem, LB_MEM_RAM, startk, rom_table_startk); - startk = rom_table_startk; - } - if ((startk == rom_table_startk) && (endk > startk)) { - unsigned long tend; - tend = rom_table_endk; - if (tend > endk) { - tend = endk; - } - lb_memory_rangek(mem, LB_MEM_TABLE, rom_table_startk, tend); - startk = tend; - } - if (endk > startk) { - lb_memory_rangek(mem, LB_MEM_RAM, startk, endk); - } - } /* Record our motheboard */ lb_mainboard(head); diff --git a/src/arch/ppc/boot/tables.c b/src/arch/ppc/boot/tables.c index 468fbcabe8..7d8bd318ba 100644 --- a/src/arch/ppc/boot/tables.c +++ b/src/arch/ppc/boot/tables.c @@ -1,12 +1,11 @@ #include <console/console.h> -#include <mem.h> #include <cpu/cpu.h> #include <boot/tables.h> #include <boot/linuxbios_tables.h> #include "linuxbios_table.h" struct lb_memory * -write_tables(struct mem_range *mem) +write_tables(void) { unsigned long low_table_start, low_table_end; unsigned long rom_table_start, rom_table_end; @@ -20,7 +19,7 @@ write_tables(struct mem_range *mem) low_table_end = 16; /* The linuxbios table must be in 0-4K or 960K-1M */ - write_linuxbios_table(mem, + write_linuxbios_table( low_table_start, low_table_end, rom_table_start >> 10, rom_table_end >> 10); diff --git a/src/arch/ppc/lib/cpu.c b/src/arch/ppc/lib/cpu.c index 7a8e46f5cd..efb914b059 100644 --- a/src/arch/ppc/lib/cpu.c +++ b/src/arch/ppc/lib/cpu.c @@ -1,35 +1,49 @@ #include <console/console.h> -#include <mem.h> #include <arch/io.h> #include <string.h> #include <cpu/cpu.h> #include <cpu/ppc/cpuid.h> #include <smp/start_stop.h> +#include "ppc.h" +#include "ppcreg.h" -static void cache_on(struct mem_range *mem) -{ -} - -static void interrupts_on() -{ -} +#error "FIXME what should call cpu_initialize?" -unsigned long cpu_initialize(struct mem_range *mem) +void cpu_initialize(void) { /* Because we busy wait at the printk spinlock. * It is important to keep the number of printed messages * from secondary cpus to a minimum, when debugging is * disabled. */ - unsigned long processor_id = this_processors_id(); - printk_notice("Initializing CPU #%d\n", processor_id); + struct device *cpu; + struct cpu_info *info; + info = cpu_info(); + + printk_notice("Initializing CPU #%d\n", info->index); + + cpu = info->cpu; + if (!cpu) { + die("CPU: missing cpu device structure"); + } - /* Turn on caching if we haven't already */ - cache_on(mem); + /* Find what type of cpu we are dealing with */ + cpu->vendor 0; /* PPC cpus do not have a vendor field */ + cpu->device = ppc_getpvr(); + display_cpuid(cpu); - display_cpuid(); +#if 0 + /* Lookup the cpu's operations */ + set_cpu_ops(cpu); - interrupts_on(); + /* Initialize the cpu */ + if (cpu->ops && cpu->ops->init) { + cpu->enabled = 1; + cpu->initialized = 1; + cpu->ops->init(); + } +#endif + /* Turn on caching if we haven't already */ printk_info("CPU #%d Initialized\n", processor_id); return processor_id; diff --git a/src/arch/ppc/lib/cpuid.c b/src/arch/ppc/lib/cpuid.c index 09a7865b1b..0ff12774bd 100644 --- a/src/arch/ppc/lib/cpuid.c +++ b/src/arch/ppc/lib/cpuid.c @@ -5,62 +5,62 @@ #include "ppcreg.h" #include <console/console.h> -void display_cpuid(void) +void display_cpuid(struct device *cpu) { - unsigned type = ppc_getpvr() >> 16; - unsigned version = ppc_getpvr() & 0xffff; - const char *cpu_string = 0; - switch(type) { + unsigned type = cpu->device >> 16; + unsigned version = cpu->device & 0xffff; + const char *cpu_string = 0; + switch(type) { case 0x0001: - cpu_string = "601"; - break; + cpu_string = "601"; + break; case 0x0003: - cpu_string = "603"; - break; + cpu_string = "603"; + break; case 0x0004: - cpu_string = "604"; - break; + cpu_string = "604"; + break; case 0x0006: - cpu_string = "603e"; - break; + cpu_string = "603e"; + break; case 0x0007: - cpu_string = "603ev"; - break; + cpu_string = "603ev"; + break; case 0x0008: - cpu_string = "750"; - break; + cpu_string = "750"; + break; case 0x0009: - cpu_string = "604e"; - break; + cpu_string = "604e"; + break; case 0x000a: - cpu_string = "604ev5 (MachV)"; - break; + cpu_string = "604ev5 (MachV)"; + break; case 0x000c: - cpu_string = "7400"; - break; + cpu_string = "7400"; + break; case 0x0032: - cpu_string = "821"; - break; + cpu_string = "821"; + break; case 0x0050: - cpu_string = "860"; - break; + cpu_string = "860"; + break; case 0x4011: - cpu_string = "405GP"; - break; + cpu_string = "405GP"; + break; case 0x5091: - cpu_string = "405GPr"; - break; + cpu_string = "405GPr"; + break; case 0x5121: - cpu_string = "405EP"; - break; + cpu_string = "405EP"; + break; case 0x800c: - cpu_string = "7410"; - break; - } - if (cpu_string) - printk_info("PowerPC %s", cpu_string); - else - printk_info("PowerPC unknown (0x%x)", type); - printk_info(" CPU, version %d.%d\n", version >> 8, version & 0xff); + cpu_string = "7410"; + break; + } + if (cpu_string) + printk_info("PowerPC %s", cpu_string); + else + printk_info("PowerPC unknown (0x%x)", type); + printk_info(" CPU, version %d.%d\n", version >> 8, version & 0xff); } diff --git a/src/boot/hardwaremain.c b/src/boot/hardwaremain.c index ecff677c88..8728a9c5a0 100644 --- a/src/boot/hardwaremain.c +++ b/src/boot/hardwaremain.c @@ -27,7 +27,6 @@ it with the version available from LANL. #include <console/console.h> -#include <mem.h> #include <version.h> #include <boot/tables.h> #include <device/device.h> @@ -35,6 +34,7 @@ it with the version available from LANL. #include <delay.h> #include <stdlib.h> #include <part/hard_reset.h> +#include <part/init_timer.h> #include <boot/elf.h> void hardwaremain(int boot_complete) diff --git a/src/config/Options.lb b/src/config/Options.lb index ac543dc54c..d3800976d4 100644 --- a/src/config/Options.lb +++ b/src/config/Options.lb @@ -702,6 +702,11 @@ end # Misc options ############################################### +define HAVE_INIT_TIMER + default 0 + export always + comment "Have a init_timer function" +end define HAVE_HARD_RESET default none export used diff --git a/src/cpu/amd/model_fxx/Config.lb b/src/cpu/amd/model_fxx/Config.lb index 945cfea5a7..044fe8670f 100644 --- a/src/cpu/amd/model_fxx/Config.lb +++ b/src/cpu/amd/model_fxx/Config.lb @@ -1,3 +1,5 @@ +uses HAVE_INIT_TIMER +default HAVE_INIT_TIMER=1 dir /cpu/x86/tsc dir /cpu/x86/fpu dir /cpu/x86/mmx diff --git a/src/cpu/x86/tsc/Config.lb b/src/cpu/x86/tsc/Config.lb index 07272ad9d7..72905eb5bb 100644 --- a/src/cpu/x86/tsc/Config.lb +++ b/src/cpu/x86/tsc/Config.lb @@ -1,5 +1,9 @@ uses CONFIG_UDELAY_TSC uses CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2 +uses HAVE_INIT_TIMER default CONFIG_TSC_X86RDTSC_CALIBRATE_WITH_TIMER2=0 -if CONFIG_UDELAY_TSC object delay_tsc.o end +if CONFIG_UDELAY_TSC + default HAVE_INIT_TIMER=1 + object delay_tsc.o +end diff --git a/src/devices/device.c b/src/devices/device.c index 5f28c0d49e..96559c5833 100644 --- a/src/devices/device.c +++ b/src/devices/device.c @@ -203,6 +203,8 @@ static void find_largest_resource(struct pick_largest_state *state, struct device *curdev; for(curdev = bus->children; curdev; curdev = curdev->sibling) { int i; + /* Ignore disabled devices */ + if (!curdev->have_resources) continue; for(i = 0; i < curdev->resources; i++) { struct resource *resource = &curdev->resource[i]; /* If it isn't the right kind of resource ignore it */ diff --git a/src/include/mem.h b/src/include/mem.h deleted file mode 100644 index e8f633b25a..0000000000 --- a/src/include/mem.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef MEM_H -#define MEM_H - -struct mem_range { - unsigned long basek; - unsigned long sizek; -}; - -/* mem_range arrays are non-overlapping, in ascending order and null terminated */ - -struct mem_range *sizeram(void); - -#endif /* MEM_H */ diff --git a/src/include/part/fallback_boot.h b/src/include/part/fallback_boot.h index 1eb2f7bffc..7d6e790f60 100644 --- a/src/include/part/fallback_boot.h +++ b/src/include/part/fallback_boot.h @@ -3,7 +3,7 @@ #ifndef ASSEMBLY -#if HAVE_FALLBACK_BOOT +#if HAVE_FALLBACK_BOOT == 1 void boot_successful(void); #else #define boot_successful() diff --git a/src/include/part/init_timer.h b/src/include/part/init_timer.h new file mode 100644 index 0000000000..d8b372dc38 --- /dev/null +++ b/src/include/part/init_timer.h @@ -0,0 +1,10 @@ +#ifndef PART_INIT_TIMER_H +#define PART_DELAY_H + +#if HAVE_INIT_TIMER == 1 +void init_timer(void); +#else +#define init_timer() do{} while(0) +#endif + +#endif /* PART_INIT_TIMER_H */ diff --git a/src/include/part/sizeram.h b/src/include/part/sizeram.h deleted file mode 100644 index 50a44f3e82..0000000000 --- a/src/include/part/sizeram.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef PART_SIZERAM_H -#define PART_SIZERAM_H - -struct mem_rang; -struct mem_range *sizeram(void); - -#endif /* PART_SIZERAM_H */ diff --git a/src/mainboard/arima/hdama/Options.lb b/src/mainboard/arima/hdama/Options.lb index 2f53627a7f..2f2df1c8ec 100644 --- a/src/mainboard/arima/hdama/Options.lb +++ b/src/mainboard/arima/hdama/Options.lb @@ -45,7 +45,7 @@ uses DEFAULT_CONSOLE_LOGLEVEL uses MAXIMUM_CONSOLE_LOGLEVEL uses MAINBOARD_POWER_ON_AFTER_POWER_FAIL uses CONFIG_CONSOLE_SERIAL8250 - +uses HAVE_INIT_TIMER ### ### Build options diff --git a/src/mainboard/arima/hdama/auto.c b/src/mainboard/arima/hdama/auto.c index 7ead2d27d0..c962197060 100644 --- a/src/mainboard/arima/hdama/auto.c +++ b/src/mainboard/arima/hdama/auto.c @@ -165,6 +165,7 @@ static void main(unsigned long bist) amd_early_mtrr_init(); enable_lapic(); init_timer(); + /* Has this cpu already booted? */ if (cpu_init_detected()) { asm volatile ("jmp __cpu_reset"); } diff --git a/src/mainboard/digitallogic/adl855pc/Config.lb b/src/mainboard/digitallogic/adl855pc/Config.lb index fb2ba53ba4..9871632bfb 100644 --- a/src/mainboard/digitallogic/adl855pc/Config.lb +++ b/src/mainboard/digitallogic/adl855pc/Config.lb @@ -202,9 +202,12 @@ end ## ## Setup RAM ## -mainboardinit cpu/p6/enable_mmx_sse.inc +mainboardinit cpu/x86/fpu/enable_fpu.inc +mainboardinit cpu/x86/mmx/emable_mmx.inc +mainboardinit cpu/x86/sse/enable_sse.inc mainboardinit ./auto.inc -mainboardinit cpu/p6/disable_mmx_sse.inc +mainboardinit cpu/x86/sse/disable_sse.inc +mainboardinit cpu/x86/mmx/disable_mmx.inc ## ## Include the secondary Configuration files @@ -212,61 +215,66 @@ mainboardinit cpu/p6/disable_mmx_sse.inc dir /pc80 config chip.h -northbridge intel/i855pm "i855pm" -# pci 0:0.0 -# pci 0:1.0 - southbridge intel/i82801dbm "i82801dbm" -# pci 0:11.0 -# pci 0:11.1 -# pci 0:11.2 -# pci 0:11.3 -# pci 0:11.4 -# pci 0:11.5 -# pci 0:11.6 -# pci 0:12.0 - register "enable_usb" = "0" - register "enable_native_ide" = "0" - register "enable_usb" = "0" - register "enable_native_ide" = "0" - superio winbond/w83627hf link 1 - pnp 2e.0 on # Floppy - io 0x60 = 0x3f0 - irq 0x70 = 6 - drq 0x74 = 2 - pnp 2e.1 off # Parallel Port - io 0x60 = 0x378 - irq 0x70 = 7 - pnp 2e.2 on # Com1 - io 0x60 = 0x3f8 - irq 0x70 = 4 - pnp 2e.3 off # Com2 - io 0x60 = 0x2f8 - irq 0x70 = 3 - pnp 2e.5 on # Keyboard - io 0x60 = 0x60 - io 0x62 = 0x64 - irq 0x70 = 1 - irq 0x72 = 12 - pnp 2e.6 off # CIR - pnp 2e.7 off # GAME_MIDI_GIPO1 - pnp 2e.8 off # GPIO2 - pnp 2e.9 off # GPIO3 - pnp 2e.a off # ACPI - pnp 2e.b on # HW Monitor - io 0x60 = 0x290 - register "com1" = "{1}" - # register "com1" = "{1, 0, 0x3f8, 4}" - # register "lpt" = "{1}" - end +## This does not look right but it is a literal conversion of the +## old version of this file. +chip northbridge/intel/i855pm + device pci_domain 0 on + device pci 0.0 on end + device pci 1.0 on end + chip southbridge/intel/i82801dbm +# pci 11.0 on end +# pci 11.1 on end +# pci 11.2 on end +# pci 11.3 on end +# pci 11.4 on end +# pci 11.5 on end +# pci 11.6 on end +# pci 12.0 on end + register "enable_usb" = "0" + register "enable_native_ide" = "0" + register "enable_usb" = "0" + register "enable_native_ide" = "0" + chip superio/winbond/w83627hf # link 1 + device pnp 2e.0 on # Floppy + io 0x60 = 0x3f0 + irq 0x70 = 6 + drq 0x74 = 2 + end + device pnp 2e.1 off # Parallel Port + io 0x60 = 0x378 + irq 0x70 = 7 + end + device pnp 2e.2 on # Com1 + io 0x60 = 0x3f8 + irq 0x70 = 4 + end + device pnp 2e.3 off # Com2 + io 0x60 = 0x2f8 + irq 0x70 = 3 + end + device pnp 2e.5 on # Keyboard + io 0x60 = 0x60 + io 0x62 = 0x64 + irq 0x70 = 1 + irq 0x72 = 12 + end + device pnp 2e.6 off end # CIR + device pnp 2e.7 off end # GAME_MIDI_GIPO1 + device pnp 2e.8 off end # GPIO2 + device pnp 2e.9 off end # GPIO3 + device pnp 2e.a off end # ACPI + device pnp 2e.b on # HW Monitor + io 0x60 = 0x290 + end + register "com1" = "{1}" + # register "com1" = "{1, 0, 0x3f8, 4}" + # register "lpt" = "{1}" + end + end + end + device apic_cluster 0 on + device cpu/intel/socket_mPGA479M + apic 0 + end end end - -cpu p6 "cpu0" - -end - -## -## Include the old serial code for those few places that still need it. -## -mainboardinit pc80/serial.inc -mainboardinit arch/i386/lib/console.inc diff --git a/src/mainboard/emulation/qemu-i386/Config.lb b/src/mainboard/emulation/qemu-i386/Config.lb index 5c3100b601..2f68d7e543 100644 --- a/src/mainboard/emulation/qemu-i386/Config.lb +++ b/src/mainboard/emulation/qemu-i386/Config.lb @@ -205,12 +205,7 @@ dir /pc80 dir /drivers/emulation/qemu config chip.h -northbridge emulation/qemu-i386 "nb_qemu" - +chip northbridge/emulation/qemu-i386 + pci_domain 0 + end end - -## -## Include the old serial code for those few places that still need it. -## -mainboardinit pc80/serial.inc -mainboardinit arch/i386/lib/console.inc diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c index f3f6ba9818..200877cec2 100644 --- a/src/northbridge/amd/amdk8/northbridge.c +++ b/src/northbridge/amd/amdk8/northbridge.c @@ -1,7 +1,6 @@ #include <console/console.h> #include <arch/io.h> #include <stdint.h> -#include <mem.h> #include <device/device.h> #include <device/pci.h> #include <device/pci_ids.h> diff --git a/src/northbridge/emulation/qemu-i386/northbridge.c b/src/northbridge/emulation/qemu-i386/northbridge.c index 6122c2c940..cd06573067 100644 --- a/src/northbridge/emulation/qemu-i386/northbridge.c +++ b/src/northbridge/emulation/qemu-i386/northbridge.c @@ -1,8 +1,6 @@ #include <console/console.h> #include <arch/io.h> #include <stdint.h> -#include <mem.h> -#include <part/sizeram.h> #include <device/device.h> #include <device/pci.h> #include <device/hypertransport.h> @@ -17,57 +15,102 @@ void hard_reset(void) printk_err("Hard_RESET!!!\n"); } -struct mem_range *sizeram(void) +#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM) + +static void pci_domain_read_resources(device_t dev) { - unsigned long mmio_basek; - static struct mem_range mem[10]; - device_t dev; - int i, idx; - unsigned char rambits; + struct resource *resource; + unsigned reg; + + /* Initialize the system wide io space constraints */ + resource = new_resource(dev, 0); + resource->base = 0x400; + resource->limit = 0xffffUL; + resource->flags = IORESOURCE_IO; + compute_allocate_resource(&dev->link[0], resource, + IORESOURCE_IO, IORESOURCE_IO); + + /* Initialize the system wide memory resources constraints */ + resource = new_resource(dev, 1); + resource->limit = 0xffffffffULL; + resource->flags = IORESOURCE_MEM; + compute_allocate_resource(&dev->link[0], resource, + IORESOURCE_MEM, IORESOURCE_MEM); +} + +static void pci_domain_set_resources(device_t dev) +{ + struct resource *resource, *last; + device_t mc_dev; + uint32_t pci_tolm; + + pci_tolm = 0xffffffffUL; + last = &dev->resource[dev->resources]; + for(resource = &dev->resource[0]; resource < last; resource++) + { + compute_allocate_resource(&dev->link[0], resource, + BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK); + + resource->flags |= IORESOURCE_STORED; + report_resource_stored(dev, resource, ""); + + if ((resource->flags & IORESOURCE_MEM) && + (pci_tolm > resource->base)) + { + pci_tolm = resource->base; + } + } - dev = dev_find_slot(0, 0); - if (!dev) { - printk_err("Cannot find PCI: 0:0\n"); - return 0; - } - mem[0].basek = 0; - mem[0].sizek = 65536; -#if 0 - idx = 1; - while(idx < sizeof(mem)/sizeof(mem[0])) { - mem[idx].basek = 0; - mem[idx].sizek = 0; - idx++; - } - for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) { - unsigned char reg; - reg = pci_read_config8(dev, ramregs[i]); - /* these are ENDING addresses, not sizes. - * if there is memory in this slot, then reg will be > rambits. - * So we just take the max, that gives us total. - * We take the highest one to cover for once and future linuxbios - * bugs. We warn about bugs. - */ - if (reg > rambits) - rambits = reg; - if (reg < rambits) - printk_err("ERROR! register 0x%x is not set!\n", - ramregs[i]); - } - printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*8*1024); - mem[0].sizek = rambits*8*1024; -#endif -#if 1 - for(i = 0; i < idx; i++) { - printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n", - i, mem[i].basek, i, mem[i].sizek); + mc_dev = dev->link[0].children; + if (mc_dev) { + unsigned long tomk, tolmk; + /* Hard code the Top of memory for now */ + tomk = 65536; + /* Compute the top of Low memory */ + tolmk = pci_tolm >> 10; + if (tolmk >= tomk) { + /* The PCI hole does not overlap memory. + */ + tolmk = tomk; + } + + /* Report the memory regions */ + idx = 10; + ram_resource(dev, idx++, 0, 640); + ram_resource(dev, idx++, 768, tolmk - 768); + if (tomk > 4*1024*1024) { + ram_resource(dev, idx++, 4096*1024, tomk - 4*1024*1024); + } } -#endif + assign_resources(&dev->link[0]); +} + +static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) +{ + max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max); + return max; +} + +static struct device_operations pci_domain_ops = { + .read_resources = pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .enable_resources = enable_childrens_resources, + .init = 0, + .scan_bus = pci_domain_scan_bus, +}; + +static void enable_dev(struct device *dev) +{ + struct device_path path; - return mem; + /* Set the operations if it is a special bus type */ + if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { + dev->ops = &pci_domain_ops; + } } struct chip_operations northbridge_emulation_qemu_i386_control = { .name = "QEMU Northbridge", + .enable_dev = enable_dev, }; diff --git a/src/northbridge/intel/e7501/northbridge.c b/src/northbridge/intel/e7501/northbridge.c index 098ad5312a..065ea54f8a 100644 --- a/src/northbridge/intel/e7501/northbridge.c +++ b/src/northbridge/intel/e7501/northbridge.c @@ -1,8 +1,6 @@ #include <console/console.h> #include <arch/io.h> #include <stdint.h> -#include <mem.h> -#include <part/sizeram.h> #include <device/device.h> #include <device/pci.h> #include <stdlib.h> @@ -172,7 +170,7 @@ static struct device_operations cpu_bus_ops = { .set_resources = cpu_bus_noop, .enable_resources = cpu_bus_noop, .init = cpu_bus_init, - .scan_bus = cpu_bus_noop, + .scan_bus = 0, }; static void enable_dev(struct device *dev) diff --git a/src/northbridge/intel/i855pm/northbridge.c b/src/northbridge/intel/i855pm/northbridge.c index b43a853eee..38a0a4a196 100644 --- a/src/northbridge/intel/i855pm/northbridge.c +++ b/src/northbridge/intel/i855pm/northbridge.c @@ -1,8 +1,6 @@ #include <console/console.h> #include <arch/io.h> #include <stdint.h> -#include <mem.h> -#include <part/sizeram.h> #include <device/device.h> #include <device/pci.h> #include <stdlib.h> @@ -10,110 +8,152 @@ #include <bitops.h> #include "chip.h" -struct mem_range *sizeram(void) +#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM) + +static void pci_domain_read_resources(device_t dev) +{ + struct resource *resource; + unsigned reg; + + /* Initialize the system wide io space constraints */ + resource = new_resource(dev, 0); + resource->base = 0x400; + resource->limit = 0xffffUL; + resource->flags = IORESOURCE_IO; + compute_allocate_resource(&dev->link[0], resource, + IORESOURCE_IO, IORESOURCE_IO); + + /* Initialize the system wide memory resources constraints */ + resource = new_resource(dev, 1); + resource->limit = 0xffffffffULL; + resource->flags = IORESOURCE_MEM; + compute_allocate_resource(&dev->link[0], resource, + IORESOURCE_MEM, IORESOURCE_MEM); +} + +static void ram_resource(device_t dev, unsigned long index, + unsigned long basek, unsigned long sizek) +{ + struct resource *resource; + + if (!sizek) { + return; + } + resource = new_resource(dev, index); + resource->base = ((resource_t)basek) << 10; + resource->size = ((resource_t)sizek) << 10; + resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \ + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + +static void pci_domain_set_resources(device_t dev) { - static struct mem_range mem[4]; - /* the units of tolm are 64 KB */ - /* the units of drb16 are 64 MB */ - uint16_t tolm, remapbase, remaplimit, drb16; - uint16_t tolm_r, remapbase_r, remaplimit_r; - uint8_t drb; - int remap_high; - device_t dev; - - dev = dev_find_slot(0, 0); // d0f0 - if (!dev) { - printk_err("Cannot find PCI: 0:0\n"); - return 0; + struct resource *resource, *last; + device_t mc_dev; + uint32_t pci_tolm; + + pci_tolm = 0xffffffffUL; + last = &dev->resource[dev->resources]; + for(resource = &dev->resource[0]; resource < last; resource++) + { + compute_allocate_resource(&dev->link[0], resource, + BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK); + + resource->flags |= IORESOURCE_STORED; + report_resource_stored(dev, resource, ""); + + if ((resource->flags & IORESOURCE_MEM) && + (pci_tolm > resource->base)) + { + pci_tolm = resource->base; + } } - - /* Calculate and report the top of low memory and - * any remapping. - */ - /* Test if the remap memory high option is set */ - remap_high = 0; -// if(get_option(&remap_high, "remap_memory_high")){ -// remap_high = 0; -// } - printk_debug("remap_high is %d\n", remap_high); - /* get out the value of the highest DRB. This tells the end of - * physical memory. The units are ticks of 64 MB i.e. 1 means - * 64 MB. - */ - drb = pci_read_config8(dev, 0x67); - drb16 = (uint16_t)drb; - if(remap_high && (drb16 > 0x08)) { - /* We only come here if we have at least 512MB of memory, - * so it is safe to hard code tolm. - * 0x2000 means 512MB + + mc_dev = dev->link[0].children; + if (mc_dev) { + /* Figure out which areas are/should be occupied by RAM. + * This is all computed in kilobytes and converted to/from + * the memory controller right at the edges. + * Having different variables in different units is + * too confusing to get right. Kilobytes are good up to + * 4 Terabytes of RAM... */ + uint16_t tolm_r; + unsigned long tomk, tolmk; + int idx; - tolm = 0x2000; - /* i.e 0x40 * 0x40 is 0x1000 which is 4 GB */ - if(drb16 > 0x0040) { - /* There is more than 4GB of memory put - * the remap window at the end of ram. + /* Get the value of the highest DRB. This tells the end of + * the physical memory. The units are ticks of 32MB + * i.e. 1 means 32MB. + */ + tomk = ((unsigned long)pci_read_config8(mc_dev, 0x63)) << 15; + /* Compute the top of Low memory */ + tolmk = pci_tolm >> 10; + if (tolmk >= tomk) { + /* The PCI hole does does not overlap the memory. */ - remapbase = drb16; - remaplimit = remapbase + 0x38; - } - else { - remapbase = 0x0040; - remaplimit = remapbase + (drb16-8); - } - } - else { - tolm = (uint16_t)((dev_root.resource[1].base >> 16)&0x0f800); - if((tolm>>8) >= (drb16<<2)) { - tolm = (drb16<<10); - remapbase = 0x3ff; - remaplimit = 0; - } - else { - remapbase = drb16; - remaplimit = remapbase + ((0x0040-(tolm>>10))-1); + tolmk = tomk; } - } - /* Write the ram configruation registers, - * preserving the reserved bits. - */ - tolm_r = pci_read_config16(dev, 0xc4); - tolm |= (tolm_r & 0x7ff); - pci_write_config16(dev, 0xc4, tolm); - remapbase_r = pci_read_config16(dev, 0xc6); - remapbase |= (remapbase_r & 0xfc00); - pci_write_config16(dev, 0xc6, remapbase); - remaplimit_r = pci_read_config16(dev, 0xc8); - remaplimit |= (remaplimit_r & 0xfc00); - pci_write_config16(dev, 0xc8, remaplimit); - -#if 0 - printk_debug("mem info tolm = %x, drb = %x, pci_memory_base = %x, remap = %x-%x\n",tolm,drb,pci_memory_base,remapbase,remaplimit); -#endif - - mem[0].basek = 0; - mem[0].sizek = 640; - mem[1].basek = 768; - /* Convert size in 64K bytes to size in K bytes */ - mem[1].sizek = (tolm << 6) - mem[1].basek; - mem[2].basek = 0; - mem[2].sizek = 0; - if ((drb << 16) > (tolm << 6)) { - /* We don't need to consider the remap window - * here because we put it immediately after the - * rest of ram. - * All we must do is calculate the amount - * of unused memory and report it at 4GB. + /* Write the ram configuration registers, + * preserving the reserved bits. */ - mem[2].basek = 4096*1024; - mem[2].sizek = (drb << 16) - (tolm << 6); + tolm_r = pci_read_config16(mc_dev, 0xc4); + tolm_r = ((tolmk >> 10) << 3) | (tolm_r & 0xf); + pci_write_config16(mc_dev, 0xc4, tolm_r); + + /* Report the memory regions */ + idx = 10; + ram_resource(dev, idx++, 0, 640); + ram_resource(dev, idx++, 768, tolmk - 768); } - mem[3].basek = 0; - mem[3].sizek = 0; - - return mem; + assign_resources(&dev->link[0]); +} + +static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) +{ + max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max); + return max; +} + +static struct device_operations pci_domain_ops = { + .read_resources = pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .enable_resources = enable_childrens_resources, + .init = 0, + .scan_bus = pci_domain_scan_bus, +}; + +static void cpu_bus_init(device_t dev) +{ + initialize_cpus(&dev->link[0]); +} + +static void cpu_bus_noop(device_t dev) +{ +} + +static struct device_operations cpu_bus_ops = { + .read_resources = cpu_bus_noop, + .set_resources = cpu_bus_noop, + .enable_resources = cpu_bus_noop, + .init = cpu_bus_init, + .scan_bus = 0, +}; + +static void enable_dev(struct device *dev) +{ + struct device_path path; + + /* Set the operations if it is a special bus type */ + if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { + dev->ops = &pci_domain_ops; + } + else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { + dev->ops = &cpu_bus_ops; + } } struct chip_operations northbridge_intel_i855pm_control = { - .name = "intel i855pm Northbridge", + .name = "intel i855pm Northbridge", + .enable_dev = enable_dev, }; diff --git a/src/northbridge/motorola/mpc107/mpc107.c b/src/northbridge/motorola/mpc107/mpc107.c index 8fdc8a9c14..e7e75b9af5 100644 --- a/src/northbridge/motorola/mpc107/mpc107.c +++ b/src/northbridge/motorola/mpc107/mpc107.c @@ -314,272 +314,272 @@ mpc107_init(void) unsigned long mpc107_config_memory(int no_banks, sdram_bank_info * bank, int for_real) { - int i, j; - char ignore[8]; - /* Convert bus clock to cycle time in 100ns units */ - unsigned cycle_time = 10 * (2500000000U / get_timer_freq()); - /* Approximate */ - unsigned access_time = cycle_time - 300; - unsigned cas_latency = 0; - unsigned rdlat; - unsigned refint; - unsigned refrec; - unsigned acttorw, acttopre; - unsigned pretoact, bstopre; - enum sdram_error_detect error_detect; - uint32_t mccr1; - uint32_t mccr2; - uint32_t mccr3; - uint32_t mccr4; - uint8_t bank_enable; - uint32_t memstart1, memstart2; - uint32_t extmemstart1, extmemstart2; - uint32_t memend1, memend2; - uint32_t extmemend1, extmemend2; - uint32_t address; - - /* Set up the ignore mask */ - for(i = 0; i < no_banks; i++) - ignore[i] = (bank[i].size == 0); + int i, j; + char ignore[8]; + /* Convert bus clock to cycle time in 100ns units */ + unsigned cycle_time = 10 * (2500000000U / get_timer_freq()); + /* Approximate */ + unsigned access_time = cycle_time - 300; + unsigned cas_latency = 0; + unsigned rdlat; + unsigned refint; + unsigned refrec; + unsigned acttorw, acttopre; + unsigned pretoact, bstopre; + enum sdram_error_detect error_detect; + uint32_t mccr1; + uint32_t mccr2; + uint32_t mccr3; + uint32_t mccr4; + uint8_t bank_enable; + uint32_t memstart1, memstart2; + uint32_t extmemstart1, extmemstart2; + uint32_t memend1, memend2; + uint32_t extmemend1, extmemend2; + uint32_t address; + + /* Set up the ignore mask */ + for(i = 0; i < no_banks; i++) + ignore[i] = (bank[i].size == 0); - /* Pick best CAS latency possible */ - for (i = 0; i < no_banks; i++) - { - if (! ignore[i]) - { - for (j = 0; j < 3; j++) - { - if (cycle_time >= bank[i].cycle_time[j] && - access_time >= bank[i].access_time[j]) + /* Pick best CAS latency possible */ + for (i = 0; i < no_banks; i++) + { + if (! ignore[i]) { - cas_latency = bank[i].cas_latency[j]; - break; + for (j = 0; j < 3; j++) + { + if (cycle_time >= bank[i].cycle_time[j] && + access_time >= bank[i].access_time[j]) + { + cas_latency = bank[i].cas_latency[j]; + break; + } + } } - } } - } - if (!cas_latency) - return 0; + if (!cas_latency) + return 0; - /* For various parameters there is a risk of clashing between banks */ - error_detect = (for_real > 1) ? ERRORS_ECC : ERRORS_NONE; - for (i = 0; i < no_banks; i++) - { - if (! ignore[i]) + /* For various parameters there is a risk of clashing between banks */ + error_detect = (for_real > 1) ? ERRORS_ECC : ERRORS_NONE; + for (i = 0; i < no_banks; i++) { - { - for (j = 0; j < 3; j++) - if (bank[i].cas_latency[j] == cas_latency) - break; - if (j == 3) - { - ignore[i] = 1; - if (! for_real) - printk_info("Disabling memory bank %d (cas latency)\n", i); + if (! ignore[i]) + { + { + for (j = 0; j < 3; j++) + if (bank[i].cas_latency[j] == cas_latency) + break; + if (j == 3) + { + ignore[i] = 1; + if (! for_real) + printk_info("Disabling memory bank %d (cas latency)\n", i); + } + if (bank[i].error_detect < error_detect) + error_detect = bank[i].error_detect; + } } - if (bank[i].error_detect < error_detect) - error_detect = bank[i].error_detect; - } - } - } - - /* Read in configuration of port X */ - mccr1 = pci_ppc_read_config32(0, 0, 0xf0); - mccr2 = pci_ppc_read_config32(0, 0, 0xf4); - mccr4 = pci_ppc_read_config32(0, 0, 0xfc); - mccr1 &= 0xfff00000; - mccr2 &= 0xffe00000; - mccr3 = 0; - mccr4 &= 0x00230000; - - pretoact = 0; - acttorw = 0; - acttopre = 0; - for (i = 0; i < no_banks; i++) - if (! ignore[i]) - { - int rowcode = -1; - if (for_real) - { - bank[i].actual_detect = error_detect; - bank[i].actual_cas = cas_latency; } + + /* Read in configuration of port X */ + mccr1 = pci_ppc_read_config32(0, 0, 0xf0); + mccr2 = pci_ppc_read_config32(0, 0, 0xf4); + mccr4 = pci_ppc_read_config32(0, 0, 0xfc); + mccr1 &= 0xfff00000; + mccr2 &= 0xffe00000; + mccr3 = 0; + mccr4 &= 0x00230000; + + pretoact = 0; + acttorw = 0; + acttopre = 0; + for (i = 0; i < no_banks; i++) + if (! ignore[i]) + { + int rowcode = -1; + if (for_real) + { + bank[i].actual_detect = error_detect; + bank[i].actual_cas = cas_latency; + } - switch (bank[i].row_bits) { - case 13: - if (bank[i].internal_banks == 4) - rowcode = 2; - else if (bank[i].internal_banks == 2) - rowcode = 1; - break; - case 12: - if (bank[i].internal_banks == 4) - rowcode = 0; - else if (bank[i].internal_banks == 2) - rowcode = 1; - break; - case 11: - if (bank[i].internal_banks == 4) - rowcode = 0; - else if (bank[i].internal_banks == 2) - rowcode = 3; - break; + switch (bank[i].row_bits) { + case 13: + if (bank[i].internal_banks == 4) + rowcode = 2; + else if (bank[i].internal_banks == 2) + rowcode = 1; + break; + case 12: + if (bank[i].internal_banks == 4) + rowcode = 0; + else if (bank[i].internal_banks == 2) + rowcode = 1; + break; + case 11: + if (bank[i].internal_banks == 4) + rowcode = 0; + else if (bank[i].internal_banks == 2) + rowcode = 3; + break; + } + if (rowcode == -1) { + ignore[i] = 1; + if (! for_real) + printk_info("Memory bank %d disabled: row bits %d and banks %d not supported\n", i, bank[i].row_bits, bank[i].internal_banks); + } else + mccr1 |= rowcode << (2 * i); + + /* Update worst case settings */ + if (! ignore[i]) { + if (bank[i].min_row_precharge > pretoact) + pretoact = bank[i].min_row_precharge; + if (bank[i].min_ras_to_cas > acttorw) + acttorw = bank[i].min_ras_to_cas; + if (bank[i].min_ras > acttopre) + acttopre = bank[i].min_ras; + } + } + + /* Now convert to clock cycles, rounding up */ + pretoact = (100 * pretoact + cycle_time - 1) / cycle_time; + acttopre = (100 * acttopre + cycle_time - 1) / cycle_time; + acttorw = (100 * acttorw + cycle_time - 1) / cycle_time; + refrec = acttopre; + bstopre = 0x240; /* Set conservative values, because we can't derive */ + refint = 1000; + + if (error_detect == ERRORS_ECC) + { + rdlat = cas_latency + 2; + mccr4 |= 0x00400000; + mccr2 |= 0x000c0001; } - if (rowcode == -1) { - ignore[i] = 1; - if (! for_real) - printk_info("Memory bank %d disabled: row bits %d and banks %d not supported\n", i, bank[i].row_bits, bank[i].internal_banks); - } else - mccr1 |= rowcode << (2 * i); - - /* Update worst case settings */ - if (! ignore[i]) { - if (bank[i].min_row_precharge > pretoact) - pretoact = bank[i].min_row_precharge; - if (bank[i].min_ras_to_cas > acttorw) - acttorw = bank[i].min_ras_to_cas; - if (bank[i].min_ras > acttopre) - acttopre = bank[i].min_ras; + else + { + rdlat = cas_latency + 1; + mccr4 |= 0x00100000; } - } - - /* Now convert to clock cycles, rounding up */ - pretoact = (100 * pretoact + cycle_time - 1) / cycle_time; - acttopre = (100 * acttopre + cycle_time - 1) / cycle_time; - acttorw = (100 * acttorw + cycle_time - 1) / cycle_time; - refrec = acttopre; - bstopre = 0x240; /* Set conservative values, because we can't derive */ - refint = 1000; - - if (error_detect == ERRORS_ECC) - { - rdlat = cas_latency + 2; - mccr4 |= 0x00400000; - mccr2 |= 0x000c0001; - } - else - { - rdlat = cas_latency + 1; - mccr4 |= 0x00100000; - } - if (pretoact > 16 || acttopre > 16 || acttorw > 16) - if (! for_real) - printk_info("Timings out of range\n"); - mccr4 |= ((pretoact & 0x0f) << 28) | ((acttopre & 0xf) << 24) | - ((acttorw & 0x0f) << 4) | - ((bstopre & 0x003) << 18) | ((bstopre & 0x3c0) >> 6) | - (cas_latency << 12) | 0x00000200 /* burst length */ ; - mccr3 |= ((bstopre & 0x03c) << 26) | - ((refrec & 0x0f) << 24) | (rdlat << 20); - mccr2 |= refint << 2; - mccr1 |= 0x00080000; /* memgo */ - - address = 0; - memstart1 = memstart2 = 0; - extmemstart1 = extmemstart2 = 0; - memend1 = memend2 = 0; - extmemend1 = extmemend2 = 0; - bank_enable = 0; - for (i = 0; i < no_banks; i++) { - if (! ignore[i]) { - uint32_t end = address + bank[i].size - 1; - bank_enable |= 1 << i; - if (i < 4) { - memstart1 |= ((address >> 20) & 0xff) << (8 * i); - extmemstart1 |= ((address >> 28) & 0x03) << (8 * i); - memend1 |= ((end >> 20) & 0xff) << (8 * i); - extmemend1 |= ((end >> 28) & 0x03) << (8 * i); - } else { - int k = i - 4; - memstart2 |= ((address >> 20) & 0xff) << (8 * k); - extmemstart2 |= ((address >> 28) & 0x03) << (8 * k); - memend2 |= ((end >> 20) & 0xff) << (8 * k); - extmemend2 |= ((end >> 28) & 0x03) << (8 * k); - } - address += bank[i].size; + if (pretoact > 16 || acttopre > 16 || acttorw > 16) + if (! for_real) + printk_info("Timings out of range\n"); + mccr4 |= ((pretoact & 0x0f) << 28) | ((acttopre & 0xf) << 24) | + ((acttorw & 0x0f) << 4) | + ((bstopre & 0x003) << 18) | ((bstopre & 0x3c0) >> 6) | + (cas_latency << 12) | 0x00000200 /* burst length */ ; + mccr3 |= ((bstopre & 0x03c) << 26) | + ((refrec & 0x0f) << 24) | (rdlat << 20); + mccr2 |= refint << 2; + mccr1 |= 0x00080000; /* memgo */ + + address = 0; + memstart1 = memstart2 = 0; + extmemstart1 = extmemstart2 = 0; + memend1 = memend2 = 0; + extmemend1 = extmemend2 = 0; + bank_enable = 0; + for (i = 0; i < no_banks; i++) { + if (! ignore[i]) { + uint32_t end = address + bank[i].size - 1; + bank_enable |= 1 << i; + if (i < 4) { + memstart1 |= ((address >> 20) & 0xff) << (8 * i); + extmemstart1 |= ((address >> 28) & 0x03) << (8 * i); + memend1 |= ((end >> 20) & 0xff) << (8 * i); + extmemend1 |= ((end >> 28) & 0x03) << (8 * i); + } else { + int k = i - 4; + memstart2 |= ((address >> 20) & 0xff) << (8 * k); + extmemstart2 |= ((address >> 28) & 0x03) << (8 * k); + memend2 |= ((end >> 20) & 0xff) << (8 * k); + extmemend2 |= ((end >> 28) & 0x03) << (8 * k); + } + address += bank[i].size; + } } - } - - if (for_real) - { - /* - * Mask MEMGO bit before setting MCCR1 - */ - mccr1 &= ~0x80000; - printk_info("MCCR1 = 0x%08x\n", mccr1); - pci_ppc_write_config32(0, 0, 0xf0, mccr1); - - printk_info("MBEN = 0x%02x\n", bank_enable); - pci_ppc_write_config8(0, 0, 0xa0, bank_enable); - printk_info("MSAR1 = 0x%08x\n", memstart1); - pci_ppc_write_config32(0, 0, 0x80, memstart1); - printk_info("MSAR2 = 0x%08x\n", memstart2); - pci_ppc_write_config32(0, 0, 0x84, memstart2); - printk_info("MSAR3 = 0x%08x\n", extmemstart1); - pci_ppc_write_config32(0, 0, 0x88, extmemstart1); - printk_info("MSAR4 = 0x%08x\n", extmemstart2); - pci_ppc_write_config32(0, 0, 0x8c, extmemstart2); - printk_info("MEAR1 = 0x%08x\n", memend1); - pci_ppc_write_config32(0, 0, 0x90, memend1); - printk_info("MEAR2 = 0x%08x\n", memend2); - pci_ppc_write_config32(0, 0, 0x94, memend2); - printk_info("MEAR3 = 0x%08x\n", extmemend1); - pci_ppc_write_config32(0, 0, 0x98, extmemend1); - printk_info("MEAR4 = 0x%08x\n", extmemend2); - pci_ppc_write_config32(0, 0, 0x9c, extmemend2); - printk_info("MCCR2 = 0x%08x\n", mccr2); - pci_ppc_write_config32(0, 0, 0xf4, mccr2); - printk_info("MCCR3 = 0x%08x\n", mccr3); - pci_ppc_write_config32(0, 0, 0xf8, mccr3); - printk_info("MCCR4 = 0x%08x\n", mccr4); - pci_ppc_write_config32(0, 0, 0xfc, mccr4); - udelay(200); - - /* - * Set MEMGO bit - */ - mccr1 |= 0x80000; - printk_info("MCCR1 = 0x%08x\n", mccr1); - pci_ppc_write_config32(0, 0, 0xf0, mccr1); - - udelay(10000); - } + if (for_real) + { + /* + * Mask MEMGO bit before setting MCCR1 + */ + mccr1 &= ~0x80000; + printk_info("MCCR1 = 0x%08x\n", mccr1); + pci_ppc_write_config32(0, 0, 0xf0, mccr1); + + printk_info("MBEN = 0x%02x\n", bank_enable); + pci_ppc_write_config8(0, 0, 0xa0, bank_enable); + printk_info("MSAR1 = 0x%08x\n", memstart1); + pci_ppc_write_config32(0, 0, 0x80, memstart1); + printk_info("MSAR2 = 0x%08x\n", memstart2); + pci_ppc_write_config32(0, 0, 0x84, memstart2); + printk_info("MSAR3 = 0x%08x\n", extmemstart1); + pci_ppc_write_config32(0, 0, 0x88, extmemstart1); + printk_info("MSAR4 = 0x%08x\n", extmemstart2); + pci_ppc_write_config32(0, 0, 0x8c, extmemstart2); + printk_info("MEAR1 = 0x%08x\n", memend1); + pci_ppc_write_config32(0, 0, 0x90, memend1); + printk_info("MEAR2 = 0x%08x\n", memend2); + pci_ppc_write_config32(0, 0, 0x94, memend2); + printk_info("MEAR3 = 0x%08x\n", extmemend1); + pci_ppc_write_config32(0, 0, 0x98, extmemend1); + printk_info("MEAR4 = 0x%08x\n", extmemend2); + pci_ppc_write_config32(0, 0, 0x9c, extmemend2); + printk_info("MCCR2 = 0x%08x\n", mccr2); + pci_ppc_write_config32(0, 0, 0xf4, mccr2); + printk_info("MCCR3 = 0x%08x\n", mccr3); + pci_ppc_write_config32(0, 0, 0xf8, mccr3); + printk_info("MCCR4 = 0x%08x\n", mccr4); + pci_ppc_write_config32(0, 0, 0xfc, mccr4); + + udelay(200); + + /* + * Set MEMGO bit + */ + mccr1 |= 0x80000; + printk_info("MCCR1 = 0x%08x\n", mccr1); + pci_ppc_write_config32(0, 0, 0xf0, mccr1); + + udelay(10000); + } - return address; + return address; } static int i2c_wait(unsigned timeout, int writing) { - uint32_t x; - while (((x = readl(MPC107_BASE + MPC107_I2CSR)) & (MPC107_I2C_CSR_MCF | MPC107_I2C_CSR_MIF)) - != (MPC107_I2C_CSR_MCF | MPC107_I2C_CSR_MIF)) { - if (ticks_since_boot() > timeout) - return -1; - } - - if (x & MPC107_I2C_CSR_MAL) { - return -1; - } - if (writing && (x & MPC107_I2C_CSR_RXAK)) { - printk_info("No RXAK\n"); - /* generate stop */ - writel(MPC107_I2C_CCR_MEN, MPC107_BASE + MPC107_I2CCR); - return -1; - } - writel(0, MPC107_BASE + MPC107_I2CSR); - return 0; + uint32_t x; + while (((x = readl(MPC107_BASE + MPC107_I2CSR)) & (MPC107_I2C_CSR_MCF | MPC107_I2C_CSR_MIF)) + != (MPC107_I2C_CSR_MCF | MPC107_I2C_CSR_MIF)) { + if (ticks_since_boot() > timeout) + return -1; + } + + if (x & MPC107_I2C_CSR_MAL) { + return -1; + } + if (writing && (x & MPC107_I2C_CSR_RXAK)) { + printk_info("No RXAK\n"); + /* generate stop */ + writel(MPC107_I2C_CCR_MEN, MPC107_BASE + MPC107_I2CCR); + return -1; + } + writel(0, MPC107_BASE + MPC107_I2CSR); + return 0; } static void mpc107_i2c_start(struct i2c_bus *bus) { - /* Set clock */ - writel(0x1031, MPC107_BASE + MPC107_I2CFDR); - /* Clear arbitration */ - writel(0, MPC107_BASE + MPC107_I2CSR); + /* Set clock */ + writel(0x1031, MPC107_BASE + MPC107_I2CFDR); + /* Clear arbitration */ + writel(0, MPC107_BASE + MPC107_I2CSR); } static void @@ -680,27 +680,27 @@ mpc107_i2c_master_read(struct i2c_bus *bus, int target, int address, count = 0; while (count < length) { - if (i2c_wait(timeout, 0) < 0) - return -1; - - /* Generate txack on next to last byte */ - if (count == length - 2) - writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_MSTA | MPC107_I2C_CCR_TXAK, MPC107_BASE + MPC107_I2CCR); - /* Generate stop on last byte */ - if (count == length - 1) - writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_TXAK, MPC107_BASE + MPC107_I2CCR); - data[count] = readl(MPC107_BASE + MPC107_I2CDR); - if (count == 0 && length == DIMM_LENGTH) { - if (data[0] == 0xff) { - printk_debug("I2C device not present\n"); - length = 3; - } else { - length = data[0]; - if (length < 3) - length = 3; + if (i2c_wait(timeout, 0) < 0) + return -1; + + /* Generate txack on next to last byte */ + if (count == length - 2) + writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_MSTA | MPC107_I2C_CCR_TXAK, MPC107_BASE + MPC107_I2CCR); + /* Generate stop on last byte */ + if (count == length - 1) + writel(MPC107_I2C_CCR_MEN | MPC107_I2C_CCR_TXAK, MPC107_BASE + MPC107_I2CCR); + data[count] = readl(MPC107_BASE + MPC107_I2CDR); + if (count == 0 && length == DIMM_LENGTH) { + if (data[0] == 0xff) { + printk_debug("I2C device not present\n"); + length = 3; + } else { + length = data[0]; + if (length < 3) + length = 3; + } } - } - count++; + count++; } /* Finish with disable master */ @@ -709,8 +709,8 @@ mpc107_i2c_master_read(struct i2c_bus *bus, int target, int address, } i2c_fn mpc107_i2c_fn = { - mpc107_i2c_start, mpc107_i2c_stop, - mpc107_i2c_master_write, mpc107_i2c_master_read + mpc107_i2c_start, mpc107_i2c_stop, + mpc107_i2c_master_write, mpc107_i2c_master_read }; /* @@ -719,36 +719,36 @@ i2c_fn mpc107_i2c_fn = { void mpc107_probe_dimms(int no_dimms, sdram_dimm_info *dimms, sdram_bank_info * bank) { - unsigned char data[256]; - unsigned dimm; - - printk_debug("Probing DIMMS...\n"); - - mpc107_i2c_start(NULL); - - for(dimm = 0; dimm < no_dimms; dimm++) - { - dimms[dimm].number = dimm; - dimms[dimm].bank1 = bank + dimm*NUM_BANKS; - dimms[dimm].bank2 = bank + dimm*NUM_BANKS + 1; - bank[dimm*NUM_BANKS].size = 0; - bank[dimm*NUM_BANKS+1].size = 0; - bank[dimm*NUM_BANKS].number = 0; - bank[dimm*NUM_BANKS+1].number = 1; - } - - - for (dimm = 0; dimm < no_dimms; dimm ++) { - unsigned limit = mpc107_i2c_master_read(NULL, 0xa0 + 2*dimm, 0, - data, DIMM_LENGTH); - - if (limit > 3) { - sdram_dimm_to_bank_info(data, dimms + dimm, 1); - memcpy(dimms[dimm].part_number, data + 73, 18); - dimms[dimm].part_number[18] = 0; - printk_debug("Part Number: %s\n", dimms[dimm].part_number); + unsigned char data[256]; + unsigned dimm; + + printk_debug("Probing DIMMS...\n"); + + mpc107_i2c_start(NULL); + + for(dimm = 0; dimm < no_dimms; dimm++) + { + dimms[dimm].number = dimm; + dimms[dimm].bank1 = bank + dimm*NUM_BANKS; + dimms[dimm].bank2 = bank + dimm*NUM_BANKS + 1; + bank[dimm*NUM_BANKS].size = 0; + bank[dimm*NUM_BANKS+1].size = 0; + bank[dimm*NUM_BANKS].number = 0; + bank[dimm*NUM_BANKS+1].number = 1; } - } - - mpc107_i2c_stop(NULL); + + + for (dimm = 0; dimm < no_dimms; dimm ++) { + unsigned limit = mpc107_i2c_master_read(NULL, 0xa0 + 2*dimm, 0, + data, DIMM_LENGTH); + + if (limit > 3) { + sdram_dimm_to_bank_info(data, dimms + dimm, 1); + memcpy(dimms[dimm].part_number, data + 73, 18); + dimms[dimm].part_number[18] = 0; + printk_debug("Part Number: %s\n", dimms[dimm].part_number); + } + } + + mpc107_i2c_stop(NULL); } diff --git a/src/northbridge/transmeta/tm5800/northbridge.c b/src/northbridge/transmeta/tm5800/northbridge.c index d3576a9143..107ebe2aed 100644 --- a/src/northbridge/transmeta/tm5800/northbridge.c +++ b/src/northbridge/transmeta/tm5800/northbridge.c @@ -1,8 +1,6 @@ #include <console/console.h> #include <arch/io.h> #include <stdint.h> -#include <mem.h> -#include <part/sizeram.h> #include <device/device.h> #include <device/pci.h> #include <device/pci_ids.h> @@ -13,111 +11,141 @@ #include "chip.h" #include "northbridge.h" -struct mem_range *sizeram(void) +#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM) + +static void pci_domain_read_resources(device_t dev) { - unsigned long mmio_basek; - static struct mem_range mem[10]; - device_t dev; - int i, idx; - -#warning "FIXME handle interleaved nodes" - dev = dev_find_slot(0, PCI_DEVFN(0x18, 1)); - if (!dev) { - printk_err("Cannot find PCI: 0:18.1\n"); - return 0; - } - mmio_basek = (dev_root.resource[1].base >> 10); - /* Round mmio_basek to something the processor can support */ - mmio_basek &= ~((1 << 6) -1); - -#if 1 -#warning "FIXME improve mtrr.c so we don't use up all of the mtrrs with a 64M MMIO hole" - /* Round the mmio hold to 256M */ - mmio_basek &= ~((256*1024) - 1); -#endif - -#if 0 - printk_debug("mmio_base: %dKB\n", mmio_basek); -#endif - - for (idx = i = 0; i < 8; i++) { - uint32_t base, limit; - unsigned basek, limitk, sizek; - base = pci_read_config32(dev, 0x40 + (i<<3)); - limit = pci_read_config32(dev, 0x44 + (i<<3)); - if ((base & ((1<<1)|(1<<0))) != ((1<<1)|(1<<0))) { - continue; - } - basek = (base & 0xffff0000) >> 2; - limitk = ((limit + 0x00010000) & 0xffff0000) >> 2; - sizek = limitk - basek; - if ((idx > 0) && - ((mem[idx - 1].basek + mem[idx - 1].sizek) == basek)) { - mem[idx -1].sizek += sizek; - } else { - mem[idx].basek = basek; - mem[idx].sizek = sizek; - idx++; - } - - /* see if we need a hole from 0xa0000 to 0xbffff */ - if ((mem[idx-1].basek < ((8*64)+(8*16))) /* 640 */ && - (mem[idx-1].sizek > ((8*64)+(16*16))) /* 768 */ ) { -#warning "FIXME: this left 0xA0000 to 0xBFFFF undefined" - mem[idx].basek = (8*64)+(16*16); - mem[idx].sizek = mem[idx-1].sizek - ((8*64)+(16*16)); - mem[idx-1].sizek = ((8*64)+(8*16)) - mem[idx-1].basek; - idx++; - } - - /* See if I need to split the region to accomodate pci memory space */ - if ((mem[idx - 1].basek <= mmio_basek) && - ((mem[idx - 1].basek + mem[idx - 1].sizek) > mmio_basek)) { - if (mem[idx - 1].basek < mmio_basek) { - unsigned pre_sizek; - pre_sizek = mmio_basek - mem[idx - 1].basek; - mem[idx].basek = mmio_basek; - mem[idx].sizek = mem[idx - 1].sizek - pre_sizek; - mem[idx - 1].sizek = pre_sizek; - idx++; - } - if ((mem[idx - 1].basek + mem[idx - 1].sizek) <= 4*1024*1024) { - idx -= 1; - } else { - mem[idx - 1].basek = 4*1024*1024; - mem[idx - 1].sizek -= (4*1024*1024 - mmio_basek); - } + struct resource *resource; + unsigned reg; + + /* Initialize the system wide io space constraints */ + resource = new_resource(dev, 0); + resource->base = 0x400; + resource->limit = 0xffffUL; + resource->flags = IORESOURCE_IO; + compute_allocate_resource(&dev->link[0], resource, + IORESOURCE_IO, IORESOURCE_IO); + + /* Initialize the system wide memory resources constraints */ + resource = new_resource(dev, 1); + resource->limit = 0xffffffffULL; + resource->flags = IORESOURCE_MEM; + compute_allocate_resource(&dev->link[0], resource, + IORESOURCE_MEM, IORESOURCE_MEM); +} + +static void ram_resource(device_t dev, unsigned long index, + unsigned long basek, unsigned long sizek) +{ + struct resource *resource; + + if (!sizek) { + return; + } + resource = new_resource(dev, index); + resource->base = ((resource_t)basek) << 10; + resource->size = ((resource_t)sizek) << 10; + resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \ + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + +static void pci_domain_set_resources(device_t dev) +{ + struct resource *resource, *last; + device_t mc_dev; + uint32_t pci_tolm; + + pci_tolm = 0xffffffffUL; + last = &dev->resource[dev->resources]; + for(resource = &dev->resource[0]; resource < last; resource++) + { + compute_allocate_resource(&dev->link[0], resource, + BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK); + + resource->flags |= IORESOURCE_STORED; + report_resource_stored(dev, resource, ""); + + if ((resource->flags & IORESOURCE_MEM) && + (pci_tolm > resource->base)) + { + pci_tolm = resource->base; + } + } + + mc_dev = dev->link[0].children; + if (mc_dev) { + /* Figure out which areas are/should be occupied by RAM. + * This is all computed in kilobytes and converted to/from + * the memory controller right at the edges. + * Having different variables in different units is + * too confusing to get right. Kilobytes are good up to + * 4 Terabytes of RAM... + */ + unsigned long tomk, tolmk; + int idx; + +#warning "This is hardcoded to 1MiB of RAM for now" + tomk = 1024; + /* Compute the top of Low memory */ + tolmk = pci_tolm >> 10; + if (tolmk >= tomk) { + /* The PCI hole does does not overlap the memory. + */ + tolmk = tomk; } + /* Report the memory regions */ + idx = 10; + ram_resource(dev, idx++, 0, 640); + ram_resource(dev, idx++, 768, tolmk - 768); } -#if 1 - for (i = 0; i < idx; i++) { - printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n", - i, mem[i].basek, i, mem[i].sizek); - } -#endif - while (idx < sizeof(mem)/sizeof(mem[0])) { - mem[idx].basek = 0; - mem[idx].sizek = 0; - idx++; - } - return mem; + assign_resources(&dev->link[0]); } -static struct device_operations northbridge_operations = { - .read_resources = tm5800_read_resources, - .set_resources = tm5800_set_resources, - .enable_resources = tm5800_enable_resources, - .init = mcf0_control_init, - .scan_bus = tm5800_scan_chains, - .enable = 0, -}; +static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) +{ + max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max); + return max; +} + +static struct device_operations pci_domain_ops = { + .read_resources = pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .enable_resources = enable_childrens_resources, + .init = 0, + .scan_bus = pci_domain_scan_bus, +}; -static struct pci_driver mcf0_driver __pci_driver = { - .ops = &northbridge_operations, - .vendor = PCI_VENDOR_ID_AMD, - .device = 0x1100, +static void cpu_bus_init(device_t dev) +{ + initialize_cpus(&dev->link[0]); +} + +static void cpu_bus_noop(device_t dev) +{ +} + +static struct device_operations cpu_bus_ops = { + .read_resources = cpu_bus_noop, + .set_resources = cpu_bus_noop, + .enable_resources = cpu_bus_noop, + .init = cpu_bus_init, + .scan_bus = 0, }; -struct chip_operations northbridge_amd_tm5800_control = { - .name = "Transmeta tm5800 Northbridge", +static void enable_dev(struct device *dev) +{ + struct device_path path; + + /* Set the operations if it is a special bus type */ + if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { + dev->ops = &pci_domain_ops; + } + else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { + dev->ops = &cpu_bus_ops; + } +} + +struct chip_operations northbridge_transmeta_tm5800_control = { + .name = "Transmeta tm5800 Northbridge", + .enable_dev = enable_dev, }; diff --git a/src/northbridge/via/vt8601/northbridge.c b/src/northbridge/via/vt8601/northbridge.c index bd3018625e..fd6b6eb916 100644 --- a/src/northbridge/via/vt8601/northbridge.c +++ b/src/northbridge/via/vt8601/northbridge.c @@ -1,8 +1,6 @@ #include <console/console.h> #include <arch/io.h> #include <stdint.h> -#include <mem.h> -#include <part/sizeram.h> #include <device/device.h> #include <device/pci.h> #include <device/hypertransport.h> @@ -12,103 +10,189 @@ #include "chip.h" #include "northbridge.h" +/* + * This fixup is based on capturing values from an Award bios. Without + * this fixup the DMA write performance is awful (i.e. hdparm -t /dev/hda is 20x + * slower than normal, ethernet drops packets). + * Apparently these registers govern some sort of bus master behavior. + */ +static void northbridge_init(device_t dev) +{ + printk_spew("VT8601 random fixup ...\n"); + pci_write_config8(dev, 0x70, 0xc0); + pci_write_config8(dev, 0x71, 0x88); + pci_write_config8(dev, 0x72, 0xec); + pci_write_config8(dev, 0x73, 0x0c); + pci_write_config8(dev, 0x74, 0x0e); + pci_write_config8(dev, 0x75, 0x81); + pci_write_config8(dev, 0x76, 0x52); +} + + + +static struct device_operations northbridge_operations = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = northbridge_init, + .enable = 0, + .ops_pci = 0, +}; + +static struct pci_driver northbridge_driver __pci_driver = { + .ops = &northbridge_operations, + .vendor = PCI_VENDOR_ID_VIA, + .device = 0x0601, /* 0x8601 is the AGP bridge? */ +}; + + + +#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM) + +static void pci_domain_read_resources(device_t dev) +{ + struct resource *resource; + unsigned reg; + + /* Initialize the system wide io space constraints */ + resource = new_resource(dev, 0); + resource->base = 0x400; + resource->limit = 0xffffUL; + resource->flags = IORESOURCE_IO; + compute_allocate_resource(&dev->link[0], resource, + IORESOURCE_IO, IORESOURCE_IO); + + /* Initialize the system wide memory resources constraints */ + resource = new_resource(dev, 1); + resource->limit = 0xffffffffULL; + resource->flags = IORESOURCE_MEM; + compute_allocate_resource(&dev->link[0], resource, + IORESOURCE_MEM, IORESOURCE_MEM); +} + +static void ram_resource(device_t dev, unsigned long index, + unsigned long basek, unsigned long sizek) +{ + struct resource *resource; + + if (!sizek) { + return; + } + resource = new_resource(dev, index); + resource->base = ((resource_t)basek) << 10; + resource->size = ((resource_t)sizek) << 10; + resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \ + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, 0x56, 0x57}; -struct mem_range *sizeram(void) +static void pci_domain_set_resources(device_t dev) { - unsigned long mmio_basek; - static struct mem_range mem[10]; - device_t dev; - int i, idx; - unsigned char rambits; - - dev = dev_find_slot(0, 0); - if (!dev) { - printk_err("Cannot find PCI: 0:0\n"); - return 0; - } - mem[0].basek = 0; - mem[0].sizek = 65536; - idx = 1; - while(idx < sizeof(mem)/sizeof(mem[0])) { - mem[idx].basek = 0; - mem[idx].sizek = 0; - idx++; - } - for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) { - unsigned char reg; - reg = pci_read_config8(dev, ramregs[i]); - /* these are ENDING addresses, not sizes. - * if there is memory in this slot, then reg will be > rambits. - * So we just take the max, that gives us total. - * We take the highest one to cover for once and future linuxbios - * bugs. We warn about bugs. - */ - if (reg > rambits) - rambits = reg; - if (reg < rambits) - printk_err("ERROR! register 0x%x is not set!\n", - ramregs[i]); - } - - printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*8*1024); - mem[0].sizek = rambits*8*1024; -#if 1 - for(i = 0; i < idx; i++) { - printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n", - i, mem[i].basek, i, mem[i].sizek); + struct resource *resource, *last; + device_t mc_dev; + uint32_t pci_tolm; + + pci_tolm = 0xffffffffUL; + last = &dev->resource[dev->resources]; + for(resource = &dev->resource[0]; resource < last; resource++) + { + compute_allocate_resource(&dev->link[0], resource, + BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK); + + resource->flags |= IORESOURCE_STORED; + report_resource_stored(dev, resource, ""); + + if ((resource->flags & IORESOURCE_MEM) && + (pci_tolm > resource->base)) + { + pci_tolm = resource->base; + } + } + + mc_dev = dev->link[0].children; + if (mc_dev) { + unsigned long tomk, tolmk; + unsigned char rambits; + int i, idx; + + for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) { + unsigned char reg; + reg = pci_read_config8(mc_dev, ramregs[i]); + /* these are ENDING addresses, not sizes. + * if there is memory in this slot, then reg will be > rambits. + * So we just take the max, that gives us total. + * We take the highest one to cover for once and future linuxbios + * bugs. We warn about bugs. + */ + if (reg > rambits) + rambits = reg; + if (reg < rambits) + printk_err("ERROR! register 0x%x is not set!\n", + ramregs[i]); + } + printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*8*1024); + tomk = ramreg*8*1024; + /* Compute the top of Low memory */ + tolmk = pci_tolm >> 10; + if (tolmk >= tomk) { + /* The PCI hole does does not overlap the memory. + */ + tolmk = tomk; + } + /* Report the memory regions */ + idx = 10; + ram_resource(dev, idx++, 0, tolmk); } -#endif + assign_resources(&dev->link[0]); +} - return mem; +static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) +{ + max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max); + return max; } -/* - * This fixup is based on capturing values from an Award bios. Without - * this fixup the DMA write performance is awful (i.e. hdparm -t /dev/hda is 20x - * slower than normal, ethernet drops packets). - * Apparently these registers govern some sort of bus master behavior. - */ -static void random_fixup() { - device_t pcidev = dev_find_slot(0, 0); +static struct device_operations pci_domain_ops = { + .read_resources = pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .enable_resources = enable_childrens_resources, + .init = 0, + .scan_bus = pci_domain_scan_bus, +}; - printk_spew("VT8601 random fixup ...\n"); - if (pcidev) { - pci_write_config8(pcidev, 0x70, 0xc0); - pci_write_config8(pcidev, 0x71, 0x88); - pci_write_config8(pcidev, 0x72, 0xec); - pci_write_config8(pcidev, 0x73, 0x0c); - pci_write_config8(pcidev, 0x74, 0x0e); - pci_write_config8(pcidev, 0x75, 0x81); - pci_write_config8(pcidev, 0x76, 0x52); - } +static void cpu_bus_init(device_t dev) +{ + initialize_cpus(&dev->link[0]); } -static void northbridge_init(struct chip *chip, enum chip_pass pass) +static void cpu_bus_noop(device_t dev) { +} - struct northbridge_via_vt8601_config *conf = - (struct northbridge_via_vt8601_config *)chip->chip_info; - - switch (pass) { - case CONF_PASS_PRE_PCI: - break; - - case CONF_PASS_POST_PCI: - break; - - case CONF_PASS_PRE_BOOT: - random_fixup(); - break; - - default: - /* nothing yet */ - break; - } +static struct device_operations cpu_bus_ops = { + .read_resources = cpu_bus_noop, + .set_resources = cpu_bus_noop, + .enable_resources = cpu_bus_noop, + .init = cpu_bus_init, + .scan_bus = 0, +}; + +static void enable_dev(struct device *dev) +{ + struct device_path path; + + /* Set the operations if it is a special bus type */ + if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { + dev->ops = &pci_domain_ops; + } + else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { + dev->ops = &cpu_bus_ops; + } } struct chip_operations northbridge_via_vt8601_control = { - .enable = northbridge_init, + .enable_dev = enable_dev, .name = "VIA vt8601 Northbridge", }; diff --git a/src/northbridge/via/vt8623/northbridge.c b/src/northbridge/via/vt8623/northbridge.c index 2d53f23353..6597da2729 100644 --- a/src/northbridge/via/vt8623/northbridge.c +++ b/src/northbridge/via/vt8623/northbridge.c @@ -1,8 +1,6 @@ #include <console/console.h> #include <arch/io.h> #include <stdint.h> -#include <mem.h> -#include <part/sizeram.h> #include <device/device.h> #include <device/pci.h> #include <device/hypertransport.h> @@ -14,151 +12,267 @@ #include "chip.h" #include "northbridge.h" -static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d }; - -struct mem_range *sizeram(void) -{ - unsigned long mmio_basek; - static struct mem_range mem[10]; - device_t dev; - int i, idx; - unsigned char rambits; - - dev = dev_find_slot(0, 0); - if (!dev) { - printk_err("Cannot find PCI: 0:0\n"); - return 0; - } - mem[0].basek = 0; - mem[0].sizek = 0xa0000 >>10; // first 640k - mem[1].basek = 0xc0000 >>10; // leave a hole for vga - idx = 2; - while(idx < sizeof(mem)/sizeof(mem[0])) { - mem[idx].basek = 0; - mem[idx].sizek = 0; - idx++; - } - for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) { - unsigned char reg; - reg = pci_read_config8(dev, ramregs[i]); - /* these are ENDING addresses, not sizes. - * if there is memory in this slot, then reg will be > rambits. - * So we just take the max, that gives us total. - * We take the highest one to cover for once and future linuxbios - * bugs. We warn about bugs. - */ - if (reg > rambits) - rambits = reg; - if (reg < rambits) - printk_err("ERROR! register 0x%x is not set!\n", - ramregs[i]); - } - - printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*16*1024); - mem[1].sizek = rambits*16*1024 - 32768 - (0xc0000 >> 10); -#if 1 - for(i = 0; i < idx; i++) { - printk_debug("mem[%d].basek = %08x mem[%d].sizek = %08x\n", - i, mem[i].basek, i, mem[i].sizek); - } -#endif - - return mem; -} - /* * This fixup is based on capturing values from an Award bios. Without * this fixup the DMA write performance is awful (i.e. hdparm -t /dev/hda is 20x * slower than normal, ethernet drops packets). * Apparently these registers govern some sort of bus master behavior. */ -static void random_fixup() { - device_t pcidev0 = dev_find_slot(0, 0); - device_t pcidev1,pcidev2; +static void norhbrige_init(device_t dev) +{ + device_t fb_dev; unsigned long fb; unsigned char c; printk_debug("VT8623 random fixup ...\n"); - if (pcidev0) { - pci_write_config8(pcidev0, 0x0d, 0x08); - pci_write_config8(pcidev0, 0x70, 0x82); - pci_write_config8(pcidev0, 0x71, 0xc8); - pci_write_config8(pcidev0, 0x72, 0x0); - pci_write_config8(pcidev0, 0x73, 0x01); - pci_write_config8(pcidev0, 0x74, 0x01); - pci_write_config8(pcidev0, 0x75, 0x08); - pci_write_config8(pcidev0, 0x76, 0x52); - pci_write_config8(pcidev0, 0x13, 0xd0); - pci_write_config8(pcidev0, 0x84, 0x80); - pci_write_config16(pcidev0,0x80, 0x610f); - pci_write_config32(pcidev0,0x88, 0x02); + pci_write_config8(dev, 0x0d, 0x08); + pci_write_config8(dev, 0x70, 0x82); + pci_write_config8(dev, 0x71, 0xc8); + pci_write_config8(dev, 0x72, 0x00); + pci_write_config8(dev, 0x73, 0x01); + pci_write_config8(dev, 0x74, 0x01); + pci_write_config8(dev, 0x75, 0x08); + pci_write_config8(dev, 0x76, 0x52); + pci_write_config8(dev, 0x13, 0xd0); + pci_write_config8(dev, 0x84, 0x80); + pci_write_config16(dev, 0x80, 0x610f); + pci_write_config32(dev, 0x88, 0x00000002); + + fb_dev = dev_find_device(PCI_VENDOR_ID_VIA, 0x3122, 0); + if (fb_dev) { + /* Fixup GART and framebuffer addresses properly. + * First setup frame buffer properly. + */ + fb = pci_read_config32(dev, 0x10); /* Base addres of framebuffer */ + printk_debug("Frame buffer at %8x\n",fb); + + c = pci_read_config8(dev, 0xe1) & 0xf0; /* size of vga */ + c |= fb>>28; /* upper nibble of frame buffer address */ + pci_write_config8(dev, 0xe1, c); + c = (fb>>20) | 1; /* enable framebuffer */ + pci_write_config8(dev, 0xe0, c); + pci_write_config8(dev, 0xe2, 0x42); /* 'cos award does */ } +} + + +static struct device_operations northbridge_operations = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = northbridge_init, + .scan_bus = pci_scan_bridge, + .ops_pci = 0, +}; + +static struct pci_driver northbridge_driver __pci_driver = { + .ops = &northbridge_ops, + .vendor = PCI_VENDOR_ID_VIA, + .device = 0x3123, +}; + +static void agp_init(device_t dev) +{ printk_debug("VT8623 AGP random fixup ...\n"); - pcidev1 = dev_find_device(PCI_VENDOR_ID_VIA,0xb091,0); - if( pcidev1) { - pci_write_config8(pcidev1,0x3e,0x0c); - pci_write_config8(pcidev1,0x40,0x83); - pci_write_config8(pcidev1,0x41,0xc5); - pci_write_config8(pcidev1,0x43,0x44); - pci_write_config8(pcidev1,0x44,0x34); - pci_write_config8(pcidev1,0x83,0x02); - } - printk_debug("VGA random fixup ...\n"); - pcidev2 = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0); - if( pcidev2 ){ - pci_write_config8(pcidev2,0x04,0x07); - pci_write_config8(pcidev2,0x0d,0x20); - } - // fixup GART and framebuffer addresses properly - // first set up frame buffer properly - fb = pci_read_config32(pcidev2,0x10); // base address of framebuffer - printk_debug("Frame buffer at %8x\n",fb); - c = pci_read_config8(pcidev0,0xe1) & 0xf0; // size of vga - c |= fb>>28; // upper nibble of frame buffer address - pci_write_config8(pcidev0,0xe1,c); - c = (fb>>20) | 1; // enable framebuffer - pci_write_config8(pcidev0,0xe0,c); - pci_write_config8(pcidev0,0xe2,0x42); // 'cos award does - + pci_write_config8(dev, 0x3e, 0x0c); + pci_write_config8(dev, 0x40, 0x83); + pci_write_config8(dev, 0x41, 0xc5); + pci_write_config8(dev, 0x43, 0x44); + pci_write_config8(dev, 0x44, 0x34); + pci_write_config8(dev, 0x83, 0x02); } -static void set_vga_mtrrs(void) + +static struct device_operations agp_operations = { + .read_resources = pci_bus_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_bus_enable_resources, + .init = agp_init, + .scan_bus = pci_scan_bridge, + .ops_pci = 0, +}; + +static struct pci_driver agp_driver __pci_driver = { + .ops = &agp_ops, + .vendor = PCI_VENDOR_ID_VIA, + .device = 0xb091, +}; + +static void vga_init(device_t dev) { - device_t pcidev = dev_find_device(PCI_VENDOR_ID_VIA,0x3122,0); unsigned long fb; + printk_debug("VGA random fixup ...\n"); + pci_write_config8(dev, 0x04, 0x07); + pci_write_config8(dev, 0x0d, 0x20); + + /* Set the vga mtrrs */ add_var_mtrr( 0xd0000000 >> 10, 0x08000000>>10, MTRR_TYPE_WRCOMB); - fb = pci_read_config32(pcidev,0x10); // get the fb address + fb = pci_read_config32(dev,0x10); // get the fb address add_var_mtrr( fb>>10, 8192, MTRR_TYPE_WRCOMB); - +} + +static struct device_operations vga_operations = { + .read_resources = pci_dev_read_resources, + .set_resources = pci_dev_set_resources, + .enable_resources = pci_dev_enable_resources, + .init = vga_init, + .ops_pci = 0, +}; + +static struct pci_driver vga_driver __pci_driver = { + .ops = &vga_ops, + .vendor = PCI_VENDOR_ID_VIA, + .device = 0x3122, +}; + + +#define BRIDGE_IO_MASK (IORESOURCE_IO | IORESOURCE_MEM) + +static void pci_domain_read_resources(device_t dev) +{ + struct resource *resource; + unsigned reg; + /* Initialize the system wide io space constraints */ + resource = new_resource(dev, 0); + resource->base = 0x400; + resource->limit = 0xffffUL; + resource->flags = IORESOURCE_IO; + compute_allocate_resource(&dev->link[0], resource, + IORESOURCE_IO, IORESOURCE_IO); + + /* Initialize the system wide memory resources constraints */ + resource = new_resource(dev, 1); + resource->limit = 0xffffffffULL; + resource->flags = IORESOURCE_MEM; + compute_allocate_resource(&dev->link[0], resource, + IORESOURCE_MEM, IORESOURCE_MEM); } -static void northbridge_init(struct chip *chip, enum chip_pass pass) +static void ram_resource(device_t dev, unsigned long index, + unsigned long basek, unsigned long sizek) { + struct resource *resource; + + if (!sizek) { + return; + } + resource = new_resource(dev, index); + resource->base = ((resource_t)basek) << 10; + resource->size = ((resource_t)sizek) << 10; + resource->flags = IORESOURCE_MEM | IORESOURCE_CACHEABLE | \ + IORESOURCE_FIXED | IORESOURCE_STORED | IORESOURCE_ASSIGNED; +} + +static const uint8_t ramregs[] = {0x5a, 0x5b, 0x5c, 0x5d }; + +static void pci_domain_set_resources(device_t dev) +{ + struct resource *resource, *last; + device_t mc_dev; + uint32_t pci_tolm; + + pci_tolm = 0xffffffffUL; + last = &dev->resource[dev->resources]; + for(resource = &dev->resource[0]; resource < last; resource++) + { + compute_allocate_resource(&dev->link[0], resource, + BRIDGE_IO_MASK, resource->flags & BRIDGE_IO_MASK); + + resource->flags |= IORESOURCE_STORED; + report_resource_stored(dev, resource, ""); - struct northbridge_via_vt8623_config *conf = - (struct northbridge_via_vt8623_config *)chip->chip_info; - - switch (pass) { - case CONF_PASS_PRE_PCI: - break; - - case CONF_PASS_POST_PCI: - random_fixup(); - break; - - case CONF_PASS_PRE_BOOT: - set_vga_mtrrs(); - break; - - default: - /* nothing yet */ - break; + if ((resource->flags & IORESOURCE_MEM) && + (pci_tolm > resource->base)) + { + pci_tolm = resource->base; + } + } + + mc_dev = dev->link[0].children; + if (mc_dev) { + unsigned long tomk, tolmk; + unsigned char rambits; + int i, idx; + + for(rambits = 0, i = 0; i < sizeof(ramregs)/sizeof(ramregs[0]); i++) { + unsigned char reg; + reg = pci_read_config8(mc_dev, ramregs[i]); + /* these are ENDING addresses, not sizes. + * if there is memory in this slot, then reg will be > rambits. + * So we just take the max, that gives us total. + * We take the highest one to cover for once and future linuxbios + * bugs. We warn about bugs. + */ + if (reg > rambits) + rambits = reg; + if (reg < rambits) + printk_err("ERROR! register 0x%x is not set!\n", + ramregs[i]); + } + printk_debug("I would set ram size to 0x%x Kbytes\n", (rambits)*16*1024); + tomk = ramreg*16*1024 - 32768; + /* Compute the top of Low memory */ + tolmk = pci_tolm >> 10; + if (tolmk >= tomk) { + /* The PCI hole does does not overlap the memory. + */ + tolmk = tomk; + } + /* Report the memory regions */ + idx = 10; + ram_resource(dev, idx++, 0, 640); /* first 640k */ + ram_resource(dev, idx++, 768, tolmk - 768); /* leave a hole for vga */ } + assign_resources(&dev->link[0]); +} + +static unsigned int pci_domain_scan_bus(device_t dev, unsigned int max) +{ + max = pci_scan_bus(&dev->link[0], PCI_DEVFN(0, 0), 0xff, max); + return max; +} + +static struct device_operations pci_domain_ops = { + .read_resources = pci_domain_read_resources, + .set_resources = pci_domain_set_resources, + .enable_resources = enable_childrens_resources, + .init = 0, + .scan_bus = pci_domain_scan_bus, +}; + +static void cpu_bus_init(device_t dev) +{ + initialize_cpus(&dev->link[0]); +} + +static void cpu_bus_noop(device_t dev) +{ +} + +static struct device_operations cpu_bus_ops = { + .read_resources = cpu_bus_noop, + .set_resources = cpu_bus_noop, + .enable_resources = cpu_bus_noop, + .init = cpu_bus_init, + .scan_bus = 0, +}; + +static void enable_dev(struct device *dev) +{ + struct device_path path; + + /* Set the operations if it is a special bus type */ + if (dev->path.type == DEVICE_PATH_PCI_DOMAIN) { + dev->ops = &pci_domain_ops; + } + else if (dev->path.type == DEVICE_PATH_APIC_CLUSTER) { + dev->ops = &cpu_bus_ops; + } } struct chip_operations northbridge_via_vt8623_control = { - .enable = northbridge_init, - .name = "VIA vt8623 Northbridge", + .enable_dev = enable_dev, + .name = "VIA vt8623 Northbridge", }; diff --git a/src/southbridge/intel/i82870/p64h2_pci_parity.c b/src/southbridge/intel/i82870/p64h2_pci_parity.c index d80f9213c9..fe27abf280 100644 --- a/src/southbridge/intel/i82870/p64h2_pci_parity.c +++ b/src/southbridge/intel/i82870/p64h2_pci_parity.c @@ -1,4 +1,3 @@ -#include <mem.h> #include <pci.h> #include <arch/io.h> #include <printk.h> |