diff options
Diffstat (limited to 'i386/i386at/gpl/linux/linux_init.c')
-rw-r--r-- | i386/i386at/gpl/linux/linux_init.c | 416 |
1 files changed, 0 insertions, 416 deletions
diff --git a/i386/i386at/gpl/linux/linux_init.c b/i386/i386at/gpl/linux/linux_init.c deleted file mode 100644 index 4e7b006a..00000000 --- a/i386/i386at/gpl/linux/linux_init.c +++ /dev/null @@ -1,416 +0,0 @@ -/* - * 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 <sys/types.h> - -#include <mach/vm_param.h> -#include <mach/vm_prot.h> -#include <mach/machine.h> - -#include <vm/vm_page.h> - -#include <i386/ipl.h> -#include <i386/pic.h> -#include <i386/pit.h> -#include <i386/machspl.h> -#include <i386/pmap.h> -#include <i386/vm_param.h> - -#include <i386at/gpl/linux/linux_emul.h> - -#define MACH_INCLUDE -#include <linux/sched.h> -#include <linux/mm.h> -#include <linux/interrupt.h> -#include <linux/delay.h> -#include <linux/ioport.h> -#include <linux/string.h> - -#include <asm/system.h> - -#include <i386/device-drivers.h> - -/* - * Set if the machine has an EISA bus. - */ -int EISA_bus = 0; - -/* - * 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 timer_bh(void *); -extern void tqueue_bh(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(); - -/* - * Amount of contiguous memory to allocate for initialization. - */ -#define CONTIG_ALLOC (512 * 1024) - -/* - * Initialize Linux drivers. - */ -void -linux_init() -{ - char *p; - int i, addr; - int (*old_clock_handler)(), old_clock_pri; - unsigned memory_start, memory_end; - vm_page_t pages; - - /* - * Initialize memory size. - */ - high_memory = phys_last_addr; - - /* - * Ensure interrupts are disabled. - */ - (void) splhigh(); - - /* - * Program counter 0 of 8253 to interrupt hz times per second. - */ - outb(PITCTL_PORT, PIT_C0|PIT_SQUAREMODE|PIT_READMODE); - outb(PITCTR0_PORT, CLKNUM / hz); - outb(PITCTR0_PORT, (CLKNUM / hz) >> 8); - - /* - * Install our clock interrupt handler. - */ - old_clock_handler = ivect[0]; - old_clock_pri = intpri[0]; - ivect[0] = linux_timer_intr; - intpri[0] = SPLHI; - form_pic_mask(); - - /* - * Enable interrupts. - */ - (void) spl0(); - - /* - * Set Linux version. - */ - linux_version_init(); - - /* - * Check if the machine has an EISA bus. - */ - p = (char *)0x0FFFD9; - if (*p++ == 'E' && *p++ == 'I' && *p++ == 'S' && *p == 'A') - EISA_bus = 1; - - /* - * Permanently allocate standard device ports. - */ - request_region(0x00, 0x20, "dma1"); - request_region(0x40, 0x20, "timer"); - request_region(0x70, 0x10, "rtc"); - request_region(0x80, 0x20, "dma page reg"); - request_region(0xc0, 0x20, "dma2"); - request_region(0xf0, 0x02, "fpu"); - request_region(0xf8, 0x08, "fpu"); - - /* - * Install software interrupt handlers. - */ - bh_base[TIMER_BH].routine = timer_bh; - bh_base[TIMER_BH].data = 0; - enable_bh(TIMER_BH); - bh_base[TQUEUE_BH].routine = tqueue_bh; - bh_base[TQUEUE_BH].data = 0; - enable_bh(TQUEUE_BH); - - /* - * 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(); - - /* - * Disable interrupts. - */ - (void) splhigh(); - - /* - * Restore clock interrupt handler. - */ - ivect[0] = old_clock_handler; - intpri[0] = old_clock_pri; - form_pic_mask(); - - 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); -} - -/* - * Calibrate delay loop. - * Lifted straight from Linux. - */ -static void -calibrate_delay() -{ - int ticks; - - /* printk("Calibrating delay loop.. "); */ - 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 >= hz) { - loops_per_sec = muldiv(loops_per_sec, - hz, ticks); - /*printk("ok - %lu.%02lu BogoMips\n", - loops_per_sec / 500000, - (loops_per_sec / 5000) % 100);*/ - return; - } - } -/* printk("failed\n");*/ -} |