diff options
Diffstat (limited to 'i386/pc/i16')
-rw-r--r-- | i386/pc/i16/i16_a20.c | 144 | ||||
-rw-r--r-- | i386/pc/i16/i16_a20.h | 32 | ||||
-rw-r--r-- | i386/pc/i16/i16_bios.h | 98 | ||||
-rw-r--r-- | i386/pc/i16/i16_exit.c | 37 | ||||
-rw-r--r-- | i386/pc/i16/i16_ext_mem.c | 151 | ||||
-rw-r--r-- | i386/pc/i16/i16_init.c | 67 | ||||
-rw-r--r-- | i386/pc/i16/i16_main.c | 38 | ||||
-rw-r--r-- | i386/pc/i16/i16_pic.c | 66 | ||||
-rw-r--r-- | i386/pc/i16/i16_putchar.c | 36 | ||||
-rw-r--r-- | i386/pc/i16/i16_raw.c | 265 | ||||
-rw-r--r-- | i386/pc/i16/i16_raw_test_a20.S | 35 | ||||
-rw-r--r-- | i386/pc/i16/i16_real_int.S | 84 | ||||
-rw-r--r-- | i386/pc/i16/i16_switch.h | 30 | ||||
-rw-r--r-- | i386/pc/i16/phys_mem_collect.c | 34 | ||||
-rw-r--r-- | i386/pc/i16/phys_mem_sources.h | 25 | ||||
-rw-r--r-- | i386/pc/i16/raw_exit.c | 41 | ||||
-rw-r--r-- | i386/pc/i16/raw_real_int.c | 46 |
17 files changed, 1229 insertions, 0 deletions
diff --git a/i386/pc/i16/i16_a20.c b/i386/pc/i16/i16_a20.c new file mode 100644 index 0000000..5e91f86 --- /dev/null +++ b/i386/pc/i16/i16_a20.c @@ -0,0 +1,144 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + + +#include <mach/machine/pio.h> +#include <mach/machine/code16.h> + +#include "i16_a20.h" + + +/* Keyboard stuff for turning on the A20 address line (gak!). */ +#define K_RDWR 0x60 /* keyboard data & cmds (read/write) */ +#define K_STATUS 0x64 /* keyboard status (read-only) */ +#define K_CMD 0x64 /* keybd ctlr command (write-only) */ + +#define K_OBUF_FUL 0x01 /* output buffer full */ +#define K_IBUF_FUL 0x02 /* input buffer full */ + +#define KC_CMD_WIN 0xd0 /* read output port */ +#define KC_CMD_WOUT 0xd1 /* write output port */ + +#define KB_ENABLE_A20 0xdf /* Linux and my BIOS uses this, + and I trust them more than Mach 3.0, + but I'd like to know what the difference is + and if it matters. */ + /*0x9f*/ /* enable A20, + enable output buffer full interrupt + enable data line + disable clock line */ +#define KB_DISABLE_A20 0xdd + + +CODE16 + + +/* + This routine ensures that the keyboard command queue is empty + (after emptying the output buffers) + + No timeout is used - if this hangs there is something wrong with + the machine, and we probably couldn't proceed anyway. + XXX should at least die properly +*/ +static void i16_empty_8042(void) +{ + int status; + +retry: + i16_nanodelay(1000); + status = i16_inb(K_STATUS); + + if (status & K_OBUF_FUL) + { + i16_nanodelay(1000); + i16_inb(K_RDWR); + goto retry; + } + + if (status & K_IBUF_FUL) + goto retry; +} + +int i16_raw_test_a20(void); + +/* Enable the A20 address line. */ +void i16_raw_enable_a20(void) +{ + int v; + + /* XXX try int 15h function 24h */ + + if (i16_raw_test_a20()) + return; + + /* PS/2 */ + v = i16_inb(0x92); + i16_nanodelay(1000); + i16_outb(0x92,v | 2); + + if (i16_raw_test_a20()) + return; + + /* AT */ + i16_empty_8042(); + i16_outb(K_CMD, KC_CMD_WOUT); + i16_empty_8042(); + i16_outb(K_RDWR, KB_ENABLE_A20); + i16_empty_8042(); + + /* Wait until the a20 line gets enabled. */ + while (!i16_raw_test_a20()); +} + +/* Disable the A20 address line. */ +void i16_raw_disable_a20(void) +{ + int v; + + if (!i16_raw_test_a20()) + return; + + /* PS/2 */ + v = i16_inb(0x92); + i16_nanodelay(1000); + i16_outb(0x92, v & ~2); + + if (!i16_raw_test_a20()) + return; + + /* AT */ + i16_empty_8042(); + i16_outb(K_CMD, KC_CMD_WOUT); + i16_empty_8042(); + i16_outb(K_RDWR, KB_DISABLE_A20); + i16_empty_8042(); + + /* Wait until the a20 line gets disabled. */ + while (i16_raw_test_a20()); +} + + +void (*i16_enable_a20)(void) = i16_raw_enable_a20; +void (*i16_disable_a20)(void) = i16_raw_disable_a20; + diff --git a/i386/pc/i16/i16_a20.h b/i386/pc/i16/i16_a20.h new file mode 100644 index 0000000..afe124b --- /dev/null +++ b/i386/pc/i16/i16_a20.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ +#ifndef _I386_PC_A20_H_ +#define _I386_PC_A20_H_ + +/* By default these point to the "raw" routines in pc/a20.c. + They can be revectored to other routines, + e.g. to use a HIMEM driver's facilities. */ +extern void (*i16_enable_a20)(void); +extern void (*i16_disable_a20)(void); + +#endif _I386_PC_A20_H_ diff --git a/i386/pc/i16/i16_bios.h b/i386/pc/i16/i16_bios.h new file mode 100644 index 0000000..29dc2d8 --- /dev/null +++ b/i386/pc/i16/i16_bios.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ +#ifndef _I16_BIOS_H_ +#define _I16_BIOS_H_ + +#include <mach/inline.h> + + +MACH_INLINE void i16_bios_putchar(int c) +{ + asm volatile("int $0x10" : : "a" (0x0e00 | (c & 0xff)), "b" (0x07)); +} + +MACH_INLINE int i16_bios_getchar() +{ + int c; + asm volatile("int $0x16" : "=a" (c) : "a" (0x0000)); + c &= 0xff; + return c; +} + +MACH_INLINE void i16_bios_warm_boot(void) +{ + asm volatile(" + cli + movw $0x40,%ax + movw %ax,%ds + movw $0x1234,0x72 + ljmp $0xffff,$0x0000 + "); +} + +MACH_INLINE void i16_bios_cold_boot(void) +{ + asm volatile(" + cli + movw $0x40,%ax + movw %ax,%ds + movw $0x0000,0x72 + ljmp $0xffff,$0x0000 + "); +} + +MACH_INLINE unsigned char i16_bios_copy_ext_mem( + unsigned src_la, unsigned dest_la, unsigned short word_count) +{ + char buf[48]; + unsigned short i, rc; + + /* Initialize the descriptor structure. */ + for (i = 0; i < sizeof(buf); i++) + buf[i] = 0; + *((unsigned short*)(buf+0x10)) = 0xffff; /* source limit */ + *((unsigned long*)(buf+0x12)) = src_la; /* source linear address */ + *((unsigned char*)(buf+0x15)) = 0x93; /* source access rights */ + *((unsigned short*)(buf+0x18)) = 0xffff; /* dest limit */ + *((unsigned long*)(buf+0x1a)) = dest_la; /* dest linear address */ + *((unsigned char*)(buf+0x1d)) = 0x93; /* dest access rights */ + +#if 0 + i16_puts("buf:"); + for (i = 0; i < sizeof(buf); i++) + i16_writehexb(buf[i]); + i16_puts(""); +#endif + + /* Make the BIOS call to perform the copy. */ + asm volatile(" + int $0x15 + " : "=a" (rc) + : "a" ((unsigned short)0x8700), + "c" (word_count), + "S" ((unsigned short)(unsigned)buf)); + + return rc >> 8; +} + +#endif _I16_BIOS_H_ diff --git a/i386/pc/i16/i16_exit.c b/i386/pc/i16/i16_exit.c new file mode 100644 index 0000000..674033a --- /dev/null +++ b/i386/pc/i16/i16_exit.c @@ -0,0 +1,37 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + +#include <mach/machine/code16.h> + +#include "i16_bios.h" + + +CODE16 + +void i16_exit(int rc) +{ + i16_puts("Press any key to reboot."); + i16_bios_getchar(); + i16_bios_warm_boot(); +} + diff --git a/i386/pc/i16/i16_ext_mem.c b/i386/pc/i16/i16_ext_mem.c new file mode 100644 index 0000000..08cbecf --- /dev/null +++ b/i386/pc/i16/i16_ext_mem.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + +#include <mach/machine/code16.h> +#include <mach/machine/vm_types.h> +#include <mach/machine/far_ptr.h> +#include <mach/machine/proc_reg.h> + +#include "i16_bios.h" +#include "phys_mem.h" +#include "vm_param.h" +#include "debug.h" + + +static vm_offset_t ext_mem_phys_free_mem; +static vm_size_t ext_mem_phys_free_size; + + +CODE32 + +int ext_mem_collect(void) +{ + if (ext_mem_phys_free_mem) + { + phys_mem_add(ext_mem_phys_free_mem, ext_mem_phys_free_size); + ext_mem_phys_free_mem = 0; + } +} + +CODE16 + +void i16_ext_mem_check() +{ + vm_offset_t ext_mem_top, ext_mem_bot; + unsigned short ext_mem_k; + + /* Find the top of available extended memory. */ + asm volatile(" + int $0x15 + jnc 1f + xorw %%ax,%%ax + 1: + " : "=a" (ext_mem_k) + : "a" (0x8800)); + ext_mem_top = 0x100000 + (vm_offset_t)ext_mem_k * 1024; + + /* XXX check for >16MB memory using function 0xc7 */ + + ext_mem_bot = 0x100000; + + /* Check for extended memory allocated bottom-up: method 1. + This uses the technique (and, loosely, the code) + described in the VCPI spec, version 1.0. */ + if (ext_mem_top > ext_mem_bot) + { + asm volatile(" + pushw %%es + + xorw %%ax,%%ax + movw %%ax,%%es + movw %%es:0x19*4+2,%%ax + movw %%ax,%%es + + movw $0x12,%%di + movw $7,%%cx + rep + cmpsb + jne 1f + + xorl %%edx,%%edx + movb %%es:0x2e,%%dl + shll $16,%%edx + movw %%es:0x2c,%%dx + + 1: + popw %%es + " : "=d" (ext_mem_bot) + : "d" (ext_mem_bot), + "S" ((unsigned short)(vm_offset_t)"VDISK V") + : "eax", "ecx", "esi", "edi"); + } + i16_assert(ext_mem_bot >= 0x100000); + + /* Check for extended memory allocated bottom-up: method 2. + This uses the technique (and, loosely, the code) + described in the VCPI spec, version 1.0. */ + if (ext_mem_top > ext_mem_bot) + { + struct { + char pad1[3]; + char V; + long DISK; + char pad2[30-8]; + unsigned short addr; + } buf; + unsigned char rc; + + i16_assert(sizeof(buf) == 0x20); + rc = i16_bios_copy_ext_mem(0x100000, kvtolin((vm_offset_t)&buf), sizeof(buf)/2); + if ((rc == 0) && (buf.V == 'V') && (buf.DISK == 'DISK')) + { + vm_offset_t new_bot = (vm_offset_t)buf.addr << 10; + i16_assert(new_bot > 0x100000); + if (new_bot > ext_mem_bot) + ext_mem_bot = new_bot; + } + } + i16_assert(ext_mem_bot >= 0x100000); + + if (ext_mem_top > ext_mem_bot) + { + ext_mem_phys_free_mem = ext_mem_bot; + ext_mem_phys_free_size = ext_mem_top - ext_mem_bot; + + /* We need to update phys_mem_max here + instead of just letting phys_mem_add() do it + when the memory is collected with phys_mem_collect(), + because VCPI initialization needs to know the top of physical memory + before phys_mem_collect() is called. + See i16_vcpi.c for the gross details. */ + if (ext_mem_top > phys_mem_max) + phys_mem_max = ext_mem_top; + } +} + +void i16_ext_mem_shutdown() +{ + /* We didn't actually allocate the memory, + so no need to deallocate it... */ +} + diff --git a/i386/pc/i16/i16_init.c b/i386/pc/i16/i16_init.c new file mode 100644 index 0000000..23a51df --- /dev/null +++ b/i386/pc/i16/i16_init.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + +#include <mach/machine/code16.h> +#include <mach/machine/proc_reg.h> + +#include "vm_param.h" + + +/* Code segment we originally had when we started in real mode. */ +unsigned short real_cs; + +/* Virtual address of physical memory. */ +vm_offset_t phys_mem_va; + +/* Physical address of start of boot image. */ +vm_offset_t boot_image_pa; + +/* Upper limit of known physical memory. */ +vm_offset_t phys_mem_max; + + +CODE16 + +#include "i16_bios.h" + +/* Called by i16_crt0 (or the equivalent) + to set up our basic 16-bit runtime environment + before calling i16_main(). */ +void i16_init(void) +{ + /* Find our code/data/everything segment. */ + real_cs = get_cs(); + + /* Find out where in physical memory we got loaded. */ + boot_image_pa = real_cs << 4; + + /* Find out where the bottom of physical memory is. + (We won't be able to directly use it for 32-bit accesses + until we actually get into 32-bit mode.) */ + phys_mem_va = -boot_image_pa; + + /* The base of linear memory is at the same place, + at least until we turn paging on. */ + linear_base_va = phys_mem_va; +} + diff --git a/i386/pc/i16/i16_main.c b/i386/pc/i16/i16_main.c new file mode 100644 index 0000000..328cceb --- /dev/null +++ b/i386/pc/i16/i16_main.c @@ -0,0 +1,38 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + +#include <mach/machine/code16.h> + + +CODE16 + +void i16_main(void) +{ + i16_init(); + + /* Grab all the memory we can find. */ + i16_ext_mem_check(); + + i16_raw_start(); +} + diff --git a/i386/pc/i16/i16_pic.c b/i386/pc/i16/i16_pic.c new file mode 100644 index 0000000..3ff2697 --- /dev/null +++ b/i386/pc/i16/i16_pic.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + +#include <mach/machine/pio.h> + +#include "pic.h" +#include "i16.h" + +CODE16 + +/* Program the PICs to use a different set of interrupt vectors. + Assumes processor I flag is off. */ +void i16_pic_set_master(int base) +{ + unsigned char old_mask; + + /* Save the original interrupt mask. */ + old_mask = inb(MASTER_OCW); PIC_DELAY(); + + /* Initialize the master PIC. */ + outb(MASTER_ICW, PICM_ICW1); PIC_DELAY(); + outb(MASTER_OCW, base); PIC_DELAY(); + outb(MASTER_OCW, PICM_ICW3); PIC_DELAY(); + outb(MASTER_OCW, PICM_ICW4); PIC_DELAY(); + + /* Restore the original interrupt mask. */ + outb(MASTER_OCW, old_mask); PIC_DELAY(); +} + +void i16_pic_set_slave(int base) +{ + unsigned char old_mask; + + /* Save the original interrupt mask. */ + old_mask = inb(SLAVES_OCW); PIC_DELAY(); + + /* Initialize the slave PIC. */ + outb(SLAVES_ICW, PICS_ICW1); PIC_DELAY(); + outb(SLAVES_OCW, base); PIC_DELAY(); + outb(SLAVES_OCW, PICS_ICW3); PIC_DELAY(); + outb(SLAVES_OCW, PICS_ICW4); PIC_DELAY(); + + /* Restore the original interrupt mask. */ + outb(SLAVES_OCW, old_mask); PIC_DELAY(); +} + diff --git a/i386/pc/i16/i16_putchar.c b/i386/pc/i16/i16_putchar.c new file mode 100644 index 0000000..365f4f8 --- /dev/null +++ b/i386/pc/i16/i16_putchar.c @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + +#include <mach/machine/code16.h> + +#include "i16_bios.h" + +CODE16 + +void i16_putchar(int ch) +{ + if (ch == '\n') + i16_bios_putchar('\r'); + i16_bios_putchar(ch); +} + diff --git a/i386/pc/i16/i16_raw.c b/i386/pc/i16/i16_raw.c new file mode 100644 index 0000000..1f705d3 --- /dev/null +++ b/i386/pc/i16/i16_raw.c @@ -0,0 +1,265 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ +/* + This file rovides a default implementation + of real/pmode switching code. + Assumes that, as far as it's concerned, + low linear address always map to physical addresses. + (The low linear mappings can be changed, + but must be changed back before switching back to real mode.) + + Provides: + i16_raw_switch_to_pmode() + i16_raw_switch_to_real_mode() + + i16_raw_start() + Called in real mode. + Initializes the pmode switching system, + switches to pmode for the first time, + and calls the 32-bit function raw_start(). + + Depends on: + + paging.h: + raw_paging_enable() + raw_paging_disable() + raw_paging_init() + + a20.h: + i16_enable_a20() + i16_disable_a20() + + real.h: + real_cs +*/ + +#include <mach/boolean.h> +#include <mach/machine/code16.h> +#include <mach/machine/vm_param.h> +#include <mach/machine/proc_reg.h> +#include <mach/machine/pio.h> +#include <mach/machine/seg.h> +#include <mach/machine/eflags.h> +#include <mach/machine/pmode.h> + +#include "config.h" +#include "cpu.h" +#include "i16.h" +#include "vm_param.h" +#include "pic.h" +#include "debug.h" +#include "i16_a20.h" +#include "i16_switch.h" + +int irq_master_base, irq_slave_base; + +/* Set to true when everything is initialized properly. */ +static boolean_t inited; + +/* Saved value of eflags register for real mode. */ +static unsigned real_eflags; + + + +#ifdef ENABLE_PAGING +#define RAW_PAGING_ENABLE() raw_paging_enable() +#define RAW_PAGING_DISABLE() raw_paging_disable() +#define RAW_PAGING_INIT() raw_paging_init() +#else +#define RAW_PAGING_ENABLE() ((void)0) +#define RAW_PAGING_DISABLE() ((void)0) +#define RAW_PAGING_INIT() ((void)0) +#endif + + +CODE16 + +void i16_raw_switch_to_pmode() +{ + /* No interrupts from now on please. */ + i16_cli(); + + /* Save the eflags register for switching back later. */ + real_eflags = get_eflags(); + + /* Enable the A20 address line. */ + i16_enable_a20(); + + /* Load the GDT. + Note that we have to do this each time we enter pmode, + not just the first, + because other real-mode programs may have switched to pmode + and back again in the meantime, trashing the GDT pointer. */ + { + struct pseudo_descriptor pdesc; + + pdesc.limit = sizeof(cpu[0].tables.gdt)-1; + pdesc.linear_base = boot_image_pa + + (vm_offset_t)&cpu[0].tables.gdt; + i16_set_gdt(&pdesc); + } + + /* Switch into protected mode. */ + i16_enter_pmode(KERNEL_16_CS); + + /* Reload all the segment registers from the new GDT. */ + set_ds(KERNEL_DS); + set_es(KERNEL_DS); + set_fs(0); + set_gs(0); + set_ss(KERNEL_DS); + + i16_do_32bit( + + if (inited) + { + /* Turn paging on if necessary. */ + RAW_PAGING_ENABLE(); + + /* Load the CPU tables into the processor. */ + cpu_tables_load(&cpu[0]); + + /* Program the PIC so the interrupt vectors won't + conflict with the processor exception vectors. */ + pic_init(PICM_VECTBASE, PICS_VECTBASE); + } + + /* Make sure our flags register is appropriate. */ + set_eflags((get_eflags() + & ~(EFL_IF | EFL_DF | EFL_NT)) + | EFL_IOPL_USER); + ); +} + +void i16_raw_switch_to_real_mode() +{ + /* Make sure interrupts are disabled. */ + cli(); + + /* Avoid sending DOS bogus coprocessor exceptions. + XXX should we save/restore all of CR0? */ + i16_clts(); + + i16_do_32bit( + /* Turn paging off if necessary. */ + RAW_PAGING_DISABLE(); + + /* Reprogram the PIC back to the settings DOS expects. */ + pic_init(0x08, 0x70); + ); + + /* Make sure all the segment registers are 16-bit. + The code segment definitely is already, + because we're running 16-bit code. */ + set_ds(KERNEL_16_DS); + set_es(KERNEL_16_DS); + set_fs(KERNEL_16_DS); + set_gs(KERNEL_16_DS); + set_ss(KERNEL_16_DS); + + /* Switch back to real mode. */ + i16_leave_pmode(real_cs); + + /* Load the real-mode segment registers. */ + set_ds(real_cs); + set_es(real_cs); + set_fs(real_cs); + set_gs(real_cs); + set_ss(real_cs); + + /* Load the real-mode IDT. */ + { + struct pseudo_descriptor pdesc; + + pdesc.limit = 0xffff; + pdesc.linear_base = 0; + i16_set_idt(&pdesc); + } + + /* Disable the A20 address line. */ + i16_disable_a20(); + + /* Restore the eflags register to its original real-mode state. + Note that this will leave interrupts disabled + since it was saved after the cli() above. */ + set_eflags(real_eflags); +} + +void i16_raw_start() +{ + /* Make sure we're not already in protected mode. */ + if (i16_get_msw() & CR0_PE) + i16_die("The processor is in an unknown " + "protected mode environment."); + + do_debug(i16_puts("Real mode detected")); + + /* Minimally initialize the GDT. */ + i16_gdt_init_temp(); + + /* Switch to protected mode for the first time. + This won't load all the processor tables and everything yet, + since they're not fully initialized. */ + i16_raw_switch_to_pmode(); + + /* We can now hop in and out of 32-bit mode at will. */ + i16_do_32bit( + + /* Now that we can access all physical memory, + collect the memory regions we discovered while in 16-bit mode + and add them to our free memory list. + We can't do this before now because the free list nodes + are stored in the free memory itself, + which is probably out of reach of our 16-bit segments. */ + phys_mem_collect(); + + /* Initialize paging if necessary. + Do it before initializing the other processor tables + because they might have to be located + somewhere in high linear memory. */ + RAW_PAGING_INIT(); + + /* Initialize the processor tables. */ + cpu_init(&cpu[0]); + + /* Initialize the hardware interrupt vectors in the IDT. */ + irq_master_base = PICM_VECTBASE; + irq_slave_base = PICS_VECTBASE; + idt_irq_init(); + + inited = TRUE; + + /* Switch to real mode and back again once more, + to make sure everything's loaded properly. */ + do_16bit( + i16_raw_switch_to_real_mode(); + i16_raw_switch_to_pmode(); + ); + + raw_start(); + ); +} + +void (*i16_switch_to_real_mode)() = i16_raw_switch_to_real_mode; +void (*i16_switch_to_pmode)() = i16_raw_switch_to_pmode; + diff --git a/i386/pc/i16/i16_raw_test_a20.S b/i386/pc/i16/i16_raw_test_a20.S new file mode 100644 index 0000000..a934e12 --- /dev/null +++ b/i386/pc/i16/i16_raw_test_a20.S @@ -0,0 +1,35 @@ + +#include <mach/machine/asm.h> + + .text + .code16 + +/* + * Test the A20 address line; return true if it is enabled. + */ +ENTRY(i16_raw_test_a20) + xorw %ax,%ax + movw %ax,%fs + notw %ax + movw %ax,%gs + + /* See if the values in already in the corresponding locations + are the same. */ + movw %fs:0,%ax + cmpw %gs:16,%ax + jnz 1f + + /* Yes; try changing one and see if they're still the same. */ + movw %ax,%dx + notw %ax + movw %ax,%fs:0 + cmpw %gs:16,%ax + movw %dx,%fs:0 + jnz 1f + + xorl %eax,%eax + ret +1: + movl $1,%eax + ret + diff --git a/i386/pc/i16/i16_real_int.S b/i386/pc/i16/i16_real_int.S new file mode 100644 index 0000000..f05077e --- /dev/null +++ b/i386/pc/i16/i16_real_int.S @@ -0,0 +1,84 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + +#include <mach/machine/asm.h> + +#include "pc_asm.h" + + .text + .code16 + +ENTRY(i16_real_int) + pushf + pushl %ebx + pushl %esi + pushl %edi + pushl %ebp + + cli + + movl 6*4(%esp),%eax + movb %al,1f+1 + + movl 7*4(%esp),%ebp + movl RCD_EAX(%ebp),%eax + movl RCD_EBX(%ebp),%ebx + movl RCD_ECX(%ebp),%ecx + movl RCD_EDX(%ebp),%edx + movl RCD_ESI(%ebp),%esi + movl RCD_EDI(%ebp),%edi + movw RCD_DS(%ebp),%ds + movw RCD_ES(%ebp),%es + /* XXX flags */ + movl RCD_EBP(%ebp),%ebp + +1: int $0 + + pushl %ebp + movl 8*4(%esp),%ebp + popl RCD_EBP(%ebp) + + movl %eax,RCD_EAX(%ebp) + movl %ebx,RCD_EBX(%ebp) + movl %ecx,RCD_ECX(%ebp) + movl %edx,RCD_EDX(%ebp) + movl %esi,RCD_ESI(%ebp) + movl %edi,RCD_EDI(%ebp) + movw %ds,RCD_DS(%ebp) + movw %es,RCD_ES(%ebp) + + pushf + popl %eax + movw %ax,RCD_FLAGS(%ebp) + + movw %ss,%ax + movw %ax,%ds + movw %ax,%es + + popl %ebp + popl %edi + popl %esi + popl %ebx + popf + ret + diff --git a/i386/pc/i16/i16_switch.h b/i386/pc/i16/i16_switch.h new file mode 100644 index 0000000..b7ecf18 --- /dev/null +++ b/i386/pc/i16/i16_switch.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ +#ifndef _I386_PC_SWITCH_H_ +#define _I386_PC_SWITCH_H_ + +/* Vectors to routines to switch between real and protected mode. */ +extern void (*i16_switch_to_real_mode)(); +extern void (*i16_switch_to_pmode)(); + +#endif _I386_PC_SWITCH_H_ diff --git a/i386/pc/i16/phys_mem_collect.c b/i386/pc/i16/phys_mem_collect.c new file mode 100644 index 0000000..bcb0c09 --- /dev/null +++ b/i386/pc/i16/phys_mem_collect.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 1995 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + +#include <mach/machine/vm_param.h> + +#include "phys_mem.h" + +void phys_mem_collect(void) +{ +#define pms(name) name##_collect(); +#include "phys_mem_sources.h" +#undef pms +} + diff --git a/i386/pc/i16/phys_mem_sources.h b/i386/pc/i16/phys_mem_sources.h new file mode 100644 index 0000000..788910d --- /dev/null +++ b/i386/pc/i16/phys_mem_sources.h @@ -0,0 +1,25 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + +pms(ext_mem) + diff --git a/i386/pc/i16/raw_exit.c b/i386/pc/i16/raw_exit.c new file mode 100644 index 0000000..5ccb69a --- /dev/null +++ b/i386/pc/i16/raw_exit.c @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + +#include <mach/machine/seg.h> +#include <mach/machine/proc_reg.h> + +#include "i16.h" +#include "debug.h" + + +void raw_exit(int rc) +{ + do_16bit( + i16_raw_switch_to_real_mode(); + i16_exit(rc); + while (1); + ); +} + +void (*real_exit)(int rc) = raw_exit; + diff --git a/i386/pc/i16/raw_real_int.c b/i386/pc/i16/raw_real_int.c new file mode 100644 index 0000000..a76d8ca --- /dev/null +++ b/i386/pc/i16/raw_real_int.c @@ -0,0 +1,46 @@ +/* + * Copyright (c) 1995-1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Bryan Ford, University of Utah CSL + */ + +#include <mach/machine/seg.h> +#include <mach/machine/proc_reg.h> + +#include "real.h" +#include "i16.h" +#include "debug.h" + + +void raw_real_int(int intnum, struct real_call_data *rcd) +{ + assert((get_cs() & 3) == 0); + + do_16bit( + unsigned int eflags; + + i16_raw_switch_to_real_mode(); + i16_real_int(intnum, rcd); + i16_raw_switch_to_pmode(); + ); +} + +void (*real_int)(int intnum, struct real_call_data *rcd) = raw_real_int; + |