From f3ed1cfad748bf5610d315afba7ec04d6338bd9b Mon Sep 17 00:00:00 2001 From: Eric Biederman Date: Sat, 16 Oct 2004 08:38:58 +0000 Subject: - HDAMA boots! - Set the bootstrap processor flag in the mptable. - Implement 64bit support in our print statements - Fix the reporting of how many cpus we are waiting to stop. It is the 1 less than the actual number of cpus running. - Actually enable cpu_initialization. - Fix firstsiblingdevice in config.g - Add IORESOURCE_FIXED to all of the resources set by config.g - Fix the apic_cluster rule to add an apic_cluster path not an apic path. - Add a div64.h to assist in the 64bit printf. git-svn-id: svn://svn.coreboot.org/coreboot/trunk@1682 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- src/arch/i386/include/div64.h | 48 +++++++++++++++++++++++++++++++++ src/arch/i386/smp/mpspec.c | 2 +- src/console/vtxprintf.c | 35 +++++++++++++----------- src/cpu/x86/lapic/lapic_cpu_init.c | 2 +- src/northbridge/amd/amdk8/northbridge.c | 19 ++++++------- 5 files changed, 80 insertions(+), 26 deletions(-) create mode 100644 src/arch/i386/include/div64.h (limited to 'src') diff --git a/src/arch/i386/include/div64.h b/src/arch/i386/include/div64.h new file mode 100644 index 0000000000..28ed8b296a --- /dev/null +++ b/src/arch/i386/include/div64.h @@ -0,0 +1,48 @@ +#ifndef __I386_DIV64 +#define __I386_DIV64 + +/* + * do_div() is NOT a C function. It wants to return + * two values (the quotient and the remainder), but + * since that doesn't work very well in C, what it + * does is: + * + * - modifies the 64-bit dividend _in_place_ + * - returns the 32-bit remainder + * + * This ends up being the most efficient "calling + * convention" on x86. + */ +#define do_div(n,base) ({ \ + unsigned long __upper, __low, __high, __mod, __base; \ + __base = (base); \ + asm("":"=a" (__low), "=d" (__high):"A" (n)); \ + __upper = __high; \ + if (__high) { \ + __upper = __high % (__base); \ + __high = __high / (__base); \ + } \ + asm("divl %2":"=a" (__low), "=d" (__mod):"rm" (__base), "0" (__low), "1" (__upper)); \ + asm("":"=A" (n):"a" (__low),"d" (__high)); \ + __mod; \ +}) + +/* + * (long)X = ((long long)divs) / (long)div + * (long)rem = ((long long)divs) % (long)div + * + * Warning, this will do an exception if X overflows. + */ +#define div_long_long_rem(a,b,c) div_ll_X_l_rem(a,b,c) + +extern inline long +div_ll_X_l_rem(long long divs, long div, long *rem) +{ + long dum2; + __asm__("divl %2":"=a"(dum2), "=d"(*rem) + : "rm"(div), "A"(divs)); + + return dum2; + +} +#endif diff --git a/src/arch/i386/smp/mpspec.c b/src/arch/i386/smp/mpspec.c index c674cf58f5..daeb78435d 100644 --- a/src/arch/i386/smp/mpspec.c +++ b/src/arch/i386/smp/mpspec.c @@ -121,7 +121,7 @@ void smp_write_processors(struct mp_config_table *mc) } cpu_flag = MPC_CPU_ENABLED; if (boot_apic_id == cpu->path.u.apic.apic_id) { - cpu_flag = MPC_CPU_ENABLED; + cpu_flag = MPC_CPU_ENABLED | MPC_CPU_BOOTPROCESSOR; } smp_write_processor(mc, cpu->path.u.apic.apic_id, apic_version, diff --git a/src/console/vtxprintf.c b/src/console/vtxprintf.c index 0f12672a50..26a5d24351 100644 --- a/src/console/vtxprintf.c +++ b/src/console/vtxprintf.c @@ -6,6 +6,7 @@ #include #include +#include /* haha, don't need ctype.c */ #define isdigit(c) ((c) >= '0' && (c) <= '9') @@ -62,14 +63,8 @@ static int skip_atoi(const char **s) #define SPECIAL 32 /* 0x */ #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ -#define do_div(n,base) ({ \ -int __res; \ -__res = ((unsigned long) n) % (unsigned) base; \ -n = ((unsigned long) n) / (unsigned) base; \ -__res; }) - -static int number(void (*tx_byte)(unsigned char byte), long num, int base, int size, int precision - ,int type) +static int number(void (*tx_byte)(unsigned char byte), + unsigned long long num, int base, int size, int precision, int type) { char c,sign,tmp[66]; const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; @@ -85,7 +80,7 @@ static int number(void (*tx_byte)(unsigned char byte), long num, int base, int s c = (type & ZEROPAD) ? '0' : ' '; sign = 0; if (type & SIGN) { - if (num < 0) { + if ((signed long long)num < 0) { sign = '-'; num = -num; size--; @@ -140,7 +135,7 @@ static int number(void (*tx_byte)(unsigned char byte), long num, int base, int s int vtxprintf(void (*tx_byte)(unsigned char byte), const char *fmt, va_list args) { int len; - unsigned long num; + unsigned long long num; int i, base; const char *s; @@ -205,6 +200,10 @@ int vtxprintf(void (*tx_byte)(unsigned char byte), const char *fmt, va_list args if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { qualifier = *fmt; ++fmt; + if (*fmt == 'l') { + qualifier = 'L'; + ++fmt; + } } /* default base */ @@ -248,7 +247,10 @@ int vtxprintf(void (*tx_byte)(unsigned char byte), const char *fmt, va_list args case 'n': - if (qualifier == 'l') { + if (qualifier == 'L') { + long long *ip = va_arg(args, long long *); + *ip = count; + } else if (qualifier == 'l') { long * ip = va_arg(args, long *); *ip = count; } else { @@ -286,16 +288,19 @@ int vtxprintf(void (*tx_byte)(unsigned char byte), const char *fmt, va_list args --fmt; continue; } - if (qualifier == 'l') + if (qualifier == 'L') { + num = va_arg(args, unsigned long long); + } else if (qualifier == 'l') { num = va_arg(args, unsigned long); - else if (qualifier == 'h') { + } else if (qualifier == 'h') { num = (unsigned short) va_arg(args, int); if (flags & SIGN) num = (short) num; - } else if (flags & SIGN) + } else if (flags & SIGN) { num = va_arg(args, int); - else + } else { num = va_arg(args, unsigned int); + } count += number(tx_byte, num, base, field_width, precision, flags); } return count; diff --git a/src/cpu/x86/lapic/lapic_cpu_init.c b/src/cpu/x86/lapic/lapic_cpu_init.c index db0cecbd06..b96c7b3586 100644 --- a/src/cpu/x86/lapic/lapic_cpu_init.c +++ b/src/cpu/x86/lapic/lapic_cpu_init.c @@ -261,7 +261,7 @@ static void initialize_other_cpus(struct bus *cpu_bus) active_count = atomic_read(&active_cpus); while(active_count > 1) { if (active_count != old_active_count) { - printk_info("Waiting for %d CPUS to stop\n", active_count); + printk_info("Waiting for %d CPUS to stop\n", active_count - 1); old_active_count = active_count; } udelay(10); diff --git a/src/northbridge/amd/amdk8/northbridge.c b/src/northbridge/amd/amdk8/northbridge.c index cb2f9fa0a7..ca5dcd82a3 100644 --- a/src/northbridge/amd/amdk8/northbridge.c +++ b/src/northbridge/amd/amdk8/northbridge.c @@ -598,7 +598,7 @@ static void pci_domain_set_resources(device_t dev) mem1->base = resource_max(mem1); } -#if 1 +#if 0 printk_debug("base1: 0x%08Lx limit1: 0x%08lx size: 0x%08Lx\n", mem1->base, mem1->limit, mem1->size); printk_debug("base2: 0x%08Lx limit2: 0x%08Lx size: 0x%08Lx\n", @@ -702,7 +702,7 @@ static struct device_operations pci_domain_ops = { .scan_bus = pci_domain_scan_bus, }; -static unsigned int scan_cpu_bus(device_t dev, unsigned int max) +static unsigned int cpu_bus_scan(device_t dev, unsigned int max) { struct bus *cpu_bus; unsigned reg; @@ -750,18 +750,19 @@ static unsigned int scan_cpu_bus(device_t dev, unsigned int max) static void cpu_bus_init(device_t dev) { - printk_debug("cpu_bus_init\n"); -#if 0 initialize_cpus(&dev->link[0]); -#endif +} + +static void cpu_bus_noop(device_t dev) +{ } static struct device_operations cpu_bus_ops = { - .read_resources = 0, - .set_resources = 0, - .enable_resources = 0, + .read_resources = cpu_bus_noop, + .set_resources = cpu_bus_noop, + .enable_resources = cpu_bus_noop, .init = cpu_bus_init, - .scan_bus = scan_cpu_bus, + .scan_bus = cpu_bus_scan, }; static void enable_dev(struct device *dev) -- cgit v1.2.3