From 59ec5ca501a2f5d9fc2b2c41d474ec30e4fd67ee Mon Sep 17 00:00:00 2001 From: Thomas Bushnell Date: Mon, 26 Apr 1999 05:49:38 +0000 Subject: 1998-12-02 OKUJI Yoshinori * configure.in: Fix linuxdev option handling. * linux/Drivers.in: Remove linuxdev option and fix linking files. * linux/Makefile.in: Replace @DEFS@ with -DLINUX_DEV. * linux/dev/arch/i386/kernel/irq.c: Include missing header files. * linux/dev/arch/i386/kernel/setup.c: Include . * linux/dev/glue/kmem.c: Add printf declaration. * linux/dev/glue/misc.c: Include . * linux/dev/init/main.c: Call linux_sched_init instead of sched_init. * linux/dev/kernel/sched.c: Add timer_bh declaration. (tqueue_bh): Fix the argument. (linux_sched_init): Renamed from sched_init. 1998-11-30 OKUJI Yoshinori Clean up linux emulation code to make it architecture-independent as much as possible. * linux: Renamed from linuxdev. * Makefile.in (objfiles): Add linux.o instead of linuxdev.o. (MAKE): New variable. Used for the linux.o target. * configure.in: Add AC_CHECK_TOOL(MAKE, make). * i386/i386/spl.h: Include , for compatibility with OSF Mach 3.0. Suggested by Elgin Lee . * linux/src: Renamed from linux/linux. * linux/dev: Renamed from linux/mach. * linux/Drivers.in (AC_INIT): Use dev/include/linux/autoconf.h, instead of mach/include/linux/autoconf.h. * Makefile.in (all): Target ../linux.o instead of ../linuxdev.o. * linux/dev/drivers/block/genhd.c: Include instead of . * linux/dev/drivers/net/auto_irq.c: Remove unneeded header files, and . * linux/dev/init/main.c: Many i386-dependent codes moved to ... * linux/dev/arch/i386/irq.c: ... here. * linux/dev/arch/i386/setup.c: New file. * linux/dev/arch/i386/linux_emul.h: Likewise. * linux/dev/arch/i386/glue/timer.c: Merged into sched.c. * linux/dev/arch/i386/glue/sched.c: Include instead of , and moved to ... * linux/dev/kernel/sched.c: ... here. * linux/dev/arch/i386/glue/block.c: Include and , instead of i386-dependent header files, and moved to ... * linux/dev/glue/blocl.c: ... here. * linux/dev/arch/i386/glue/net.c: Include and , instead of i386-dependent header files, and moved to ... * linux/dev/glue/net.c: ... here. * linux/dev/arch/i386/glue/misc.c: Remove `x86' and moved to ... * linux/dev/glue/misc.c: ... here. * linux/dev/arch/i386/glue/kmem.c: Moved to ... * linux/dev/glue/kmem.c: ... here. --- linux/dev/init/main.c | 391 +++++++++++++++++++++++++++++++++++++++++++++++ linux/dev/init/version.c | 32 ++++ 2 files changed, 423 insertions(+) create mode 100644 linux/dev/init/main.c create mode 100644 linux/dev/init/version.c (limited to 'linux/dev/init') diff --git a/linux/dev/init/main.c b/linux/dev/init/main.c new file mode 100644 index 0000000..0c14353 --- /dev/null +++ b/linux/dev/init/main.c @@ -0,0 +1,391 @@ +/* + * Linux initialization. + * + * Copyright (C) 1996 The University of Utah and the Computer Systems + * Laboratory at the University of Utah (CSL) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Shantanu Goel, University of Utah CSL + */ + +/* + * linux/init/main.c + * + * Copyright (C) 1991, 1992 Linus Torvalds + */ + +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include + +#define MACH_INCLUDE +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +/* + * Timing loop count. + */ +unsigned long loops_per_sec = 1; + +/* + * End of physical memory. + */ +unsigned long high_memory; + +/* + * Flag to indicate auto-configuration is in progress. + */ +int linux_auto_config = 1; + +/* + * Hard drive parameters obtained from the BIOS. + */ +struct drive_info_struct +{ + char dummy[32]; +} drive_info; + +/* + * Forward declarations. + */ +static void calibrate_delay (void); + +extern int hz; +extern vm_offset_t phys_last_addr; + +extern void *alloc_contig_mem (unsigned, unsigned, unsigned, vm_page_t *); +extern void free_contig_mem (vm_page_t); +extern void init_IRQ (void); +extern void restore_IRQ (void); +extern void startrtclock (void); +extern void linux_version_init (void); +extern void linux_kmem_init (void); +extern unsigned long pci_init (unsigned long, unsigned long); +extern void linux_net_emulation_init (void); +extern void device_setup (void); +extern void linux_printk (char *,...); +extern int linux_timer_intr (void); +extern spl_t spl0 (void); +extern spl_t splhigh (void); +extern void form_pic_mask (void); +extern int linux_bad_intr (int); +extern int prtnull (); +extern int intnull (); +extern void linux_sched_init (void); + + +/* + * Amount of contiguous memory to allocate for initialization. + */ +#define CONTIG_ALLOC (512 * 1024) + +/* + * Initialize Linux drivers. + */ +void +linux_init (void) +{ + int addr; + unsigned memory_start, memory_end; + vm_page_t pages; + + /* + * Initialize memory size. + */ + high_memory = phys_last_addr; + init_IRQ (); + linux_sched_init (); + + /* + * Set loop count. + */ + calibrate_delay (); + + /* + * Initialize drive info. + */ + addr = *((unsigned *) phystokv (0x104)); + memcpy (&drive_info, + (void *) ((addr & 0xffff) + ((addr >> 12) & 0xffff0)), 16); + addr = *((unsigned *) phystokv (0x118)); + memcpy ((char *) &drive_info + 16, + (void *) ((addr & 0xffff) + ((addr >> 12) & 0xffff0)), 16); + + /* + * Initialize Linux memory allocator. + */ + linux_kmem_init (); + + /* + * Allocate contiguous memory below 16 MB. + */ + memory_start = (unsigned long) alloc_contig_mem (CONTIG_ALLOC, + 16 * 1024 * 1024, + 0, &pages); + if (memory_start == 0) + panic ("linux_init: alloc_contig_mem failed"); + memory_end = memory_start + CONTIG_ALLOC; + + /* + * Initialize PCI bus. + */ + memory_start = pci_init (memory_start, memory_end); + + if (memory_start > memory_end) + panic ("linux_init: ran out memory"); + + /* + * Free unused memory. + */ + while (pages && pages->phys_addr < round_page (memory_start)) + pages = (vm_page_t) pages->pageq.next; + if (pages) + free_contig_mem (pages); + + /* + * Initialize devices. + */ +#ifdef CONFIG_INET + linux_net_emulation_init (); +#endif + cli (); + device_setup (); + + restore_IRQ (); + linux_auto_config = 0; +} + +#ifndef NBPW +#define NBPW 32 +#endif + +/* + * Allocate contiguous memory with the given constraints. + * This routine is horribly inefficient but it is presently + * only used during initialization so it's not that bad. + */ +void * +alloc_contig_mem (unsigned size, unsigned limit, + unsigned mask, vm_page_t * pages) +{ + int i, j, bits_len; + unsigned *bits, len; + void *m; + vm_page_t p, page_list, tail, prev; + vm_offset_t addr, max_addr; + + if (size == 0) + return (NULL); + size = round_page (size); + if ((size >> PAGE_SHIFT) > vm_page_free_count) + return (NULL); + + /* Allocate bit array. */ + max_addr = phys_last_addr; + if (max_addr > limit) + max_addr = limit; + bits_len = ((((max_addr >> PAGE_SHIFT) + NBPW - 1) / NBPW) + * sizeof (unsigned)); + bits = (unsigned *) kalloc (bits_len); + if (!bits) + return (NULL); + memset (bits, 0, bits_len); + + /* + * Walk the page free list and set a bit for every usable page. + */ + simple_lock (&vm_page_queue_free_lock); + p = vm_page_queue_free; + while (p) + { + if (p->phys_addr < limit) + (bits[(p->phys_addr >> PAGE_SHIFT) / NBPW] + |= 1 << ((p->phys_addr >> PAGE_SHIFT) % NBPW)); + p = (vm_page_t) p->pageq.next; + } + + /* + * Scan bit array for contiguous pages. + */ + len = 0; + m = NULL; + for (i = 0; len < size && i < bits_len / sizeof (unsigned); i++) + for (j = 0; len < size && j < NBPW; j++) + if (!(bits[i] & (1 << j))) + { + len = 0; + m = NULL; + } + else + { + if (len == 0) + { + addr = ((vm_offset_t) (i * NBPW + j) + << PAGE_SHIFT); + if ((addr & mask) == 0) + { + len += PAGE_SIZE; + m = (void *) addr; + } + } + else + len += PAGE_SIZE; + } + + if (len != size) + { + simple_unlock (&vm_page_queue_free_lock); + kfree ((vm_offset_t) bits, bits_len); + return (NULL); + } + + /* + * Remove pages from free list + * and construct list to return to caller. + */ + page_list = NULL; + for (len = 0; len < size; len += PAGE_SIZE, addr += PAGE_SIZE) + { + prev = NULL; + for (p = vm_page_queue_free; p; p = (vm_page_t) p->pageq.next) + { + if (p->phys_addr == addr) + break; + prev = p; + } + if (!p) + panic ("alloc_contig_mem: page not on free list"); + if (prev) + prev->pageq.next = p->pageq.next; + else + vm_page_queue_free = (vm_page_t) p->pageq.next; + p->free = FALSE; + p->pageq.next = NULL; + if (!page_list) + page_list = tail = p; + else + { + tail->pageq.next = (queue_entry_t) p; + tail = p; + } + vm_page_free_count--; + } + + simple_unlock (&vm_page_queue_free_lock); + kfree ((vm_offset_t) bits, bits_len); + if (pages) + *pages = page_list; + return (m); +} + +/* + * Free memory allocated by alloc_contig_mem. + */ +void +free_contig_mem (vm_page_t pages) +{ + int i; + vm_page_t p; + + for (p = pages, i = 0; p->pageq.next; p = (vm_page_t) p->pageq.next, i++) + p->free = TRUE; + p->free = TRUE; + simple_lock (&vm_page_queue_free_lock); + vm_page_free_count += i + 1; + p->pageq.next = (queue_entry_t) vm_page_queue_free; + vm_page_queue_free = pages; + simple_unlock (&vm_page_queue_free_lock); +} + +/* This is the number of bits of precision for the loops_per_second. Each + * bit takes on average 1.5/HZ seconds. This (like the original) is a little + * better than 1% + */ +#define LPS_PREC 8 + +static void +calibrate_delay (void) +{ + int ticks; + int loopbit; + int lps_precision = LPS_PREC; + + loops_per_sec = (1 << 12); + +#ifndef MACH + printk ("Calibrating delay loop.. "); +#endif + while (loops_per_sec <<= 1) + { + /* wait for "start of" clock tick */ + ticks = jiffies; + while (ticks == jiffies) + /* nothing */ ; + /* Go .. */ + ticks = jiffies; + __delay (loops_per_sec); + ticks = jiffies - ticks; + if (ticks) + break; + } + + /* Do a binary approximation to get loops_per_second set to equal one clock + * (up to lps_precision bits) + */ + loops_per_sec >>= 1; + loopbit = loops_per_sec; + while (lps_precision-- && (loopbit >>= 1)) + { + loops_per_sec |= loopbit; + ticks = jiffies; + while (ticks == jiffies); + ticks = jiffies; + __delay (loops_per_sec); + if (jiffies != ticks) /* longer than 1 tick */ + loops_per_sec &= ~loopbit; + } + + /* finally, adjust loops per second in terms of seconds instead of clocks */ + loops_per_sec *= HZ; + /* Round the value and print it */ +#ifndef MACH + printk ("ok - %lu.%02lu BogoMIPS\n", + (loops_per_sec + 2500) / 500000, + ((loops_per_sec + 2500) / 5000) % 100); +#endif + +#if defined(__SMP__) && defined(__i386__) + smp_loops_per_tick = loops_per_sec / 400; +#endif +} diff --git a/linux/dev/init/version.c b/linux/dev/init/version.c new file mode 100644 index 0000000..1989483 --- /dev/null +++ b/linux/dev/init/version.c @@ -0,0 +1,32 @@ +/* + * linux/version.c + * + * Copyright (C) 1992 Theodore Ts'o + * + * May be freely distributed as part of Linux. + */ + +#define MACH_INCLUDE +#include +#include +#include +#include + +/* make the "checkconfig" script happy: we really need to include config.h */ +#ifdef CONFIG_BOGUS +#endif + +#define version(a) Version_ ## a +#define version_string(a) version(a) + +int version_string (LINUX_VERSION_CODE) = 0; + +struct new_utsname system_utsname = +{ + UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION, + UTS_MACHINE, UTS_DOMAINNAME +}; + +const char *linux_banner = +"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@" +LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n"; -- cgit v1.2.3