diff options
Diffstat (limited to 'i386/pc')
44 files changed, 3401 insertions, 0 deletions
diff --git a/i386/pc/Makerules b/i386/pc/Makerules new file mode 100644 index 0000000..eaa1f24 --- /dev/null +++ b/i386/pc/Makerules @@ -0,0 +1,30 @@ +# +# Copyright (c) 1994 The University of Utah and +# the Center for Software Science (CSS). All rights reserved. +# +# Permission to use, copy, modify and distribute this software and its +# documentation is hereby granted, provided that both the copyright +# notice and this permission notice appear in all copies of the +# software, derivative works or modified versions, and any portions +# thereof, and that both notices appear in supporting documentation. +# +# THE UNIVERSITY OF UTAH AND CSS ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS +# IS" CONDITION. THE UNIVERSITY OF UTAH AND CSS DISCLAIM ANY LIABILITY OF +# ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. +# +# CSS requests users of this software to return to css-dist@cs.utah.edu any +# improvements that they make and grant CSS redistribution rights. +# +# Author: Bryan Ford, University of Utah CSS +# +ifndef _mach4_i386_kernel_pc_makerules_ +_mach4_i386_kernel_pc_makerules = yes + + +CLEAN_FILES += pc_asm.h +i16_real_int.o: pc_asm.h + +include $(MSRCDIR)/kernel/util/Makerules + + +endif diff --git a/i386/pc/NOTES b/i386/pc/NOTES new file mode 100644 index 0000000..d165aa4 --- /dev/null +++ b/i386/pc/NOTES @@ -0,0 +1,34 @@ + + +i16_raw.c: + Provides 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 + diff --git a/i386/pc/debug.h b/i386/pc/debug.h new file mode 100644 index 0000000..6265082 --- /dev/null +++ b/i386/pc/debug.h @@ -0,0 +1,71 @@ +/* + * 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 _KUKM_I386_PC_DEBUG_H_ +#define _KUKM_I386_PC_DEBUG_H_ + +#ifdef ASSEMBLER +#ifdef DEBUG + + +/* Poke a character directly onto the VGA text display, + as a very quick, mostly-reliable status indicator. + Assumes ss is a kernel data segment register. */ +#define POKE_STATUS(char,scratch) \ + ss/*XXX gas bug */ ;\ + movl %ss:_phys_mem_va,scratch ;\ + addl $0xb8000+80*2*13+40*2,scratch ;\ + movb char,%ss:(scratch) ;\ + movb $0xf0,%ss:1(scratch) + + +#else !DEBUG + +#define POKE_STATUS(char,scratch) + +#endif !DEBUG +#else !ASSEMBLER +#ifdef DEBUG + +#include <mach/machine/vm_types.h> + + +#define POKE_STATUS(string) \ + ({ unsigned char *s = (string); \ + extern vm_offset_t phys_mem_va; \ + short *d = (short*)(phys_mem_va+0xb8000+80*2*13+40*2); \ + while (*s) { (*d++) = 0x3000 | (*s++); } \ + *d = ' '; \ + }) + + +#else !DEBUG + +#define POKE_STATUS(char) + +#endif !DEBUG +#endif !ASSEMBLER + + +#include_next "debug.h" + +#endif _KUKM_I386_PC_DEBUG_H_ diff --git a/i386/pc/exit.c b/i386/pc/exit.c new file mode 100644 index 0000000..59c9383 --- /dev/null +++ b/i386/pc/exit.c @@ -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 + */ + +#include "real.h" + +void _exit(int rc) +{ + about_to_die(rc); + + (*real_exit)(rc); +} + diff --git a/i386/pc/gdt.h b/i386/pc/gdt.h new file mode 100644 index 0000000..8dae857 --- /dev/null +++ b/i386/pc/gdt.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 + */ + +#include_next "gdt.h" + +/* If we have a REAL_TSS, use that as our DEFAULT_TSS if necessary. + (The DEFAULT_TSS gets loaded by cpu_tables_load() upon switching to pmode.) */ +#if defined(ENABLE_REAL_TSS) && !defined(DEFAULT_TSS) +#define DEFAULT_TSS REAL_TSS +#define DEFAULT_TSS_IDX REAL_TSS_IDX +#endif + diff --git a/i386/pc/gdt_sels.h b/i386/pc/gdt_sels.h new file mode 100644 index 0000000..18e0907 --- /dev/null +++ b/i386/pc/gdt_sels.h @@ -0,0 +1,34 @@ +/* + * 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_next "gdt_sels.h" + +#ifdef ENABLE_REAL_TSS + +/* This is a special TSS with a full IO bitmap + that allows access to all I/O ports in v86 mode. + It's used for making calls to the real-mode BIOS (or DOS). */ +gdt_sel(REAL_TSS) + +#endif + 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; + diff --git a/i386/pc/ipl.h b/i386/pc/ipl.h new file mode 100644 index 0000000..5f40660 --- /dev/null +++ b/i386/pc/ipl.h @@ -0,0 +1,74 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* +Copyright (c) 1988,1989 Prime Computer, Inc. Natick, MA 01760 +All Rights Reserved. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and +without fee is hereby granted, provided that the above +copyright notice appears in all copies and that both the +copyright notice and this permission notice appear in +supporting documentation, and that the name of Prime +Computer, Inc. not be used in advertising or publicity +pertaining to distribution of the software without +specific, written prior permission. + +THIS SOFTWARE IS PROVIDED "AS IS", AND PRIME COMPUTER, +INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN +NO EVENT SHALL PRIME COMPUTER, INC. BE LIABLE FOR ANY +SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN ACTION OF CONTRACT, NEGLIGENCE, OR +OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + + +#define SPL0 0 +#define SPL1 1 +#define SPL2 2 +#define SPL3 3 +#define SPL4 4 +#define SPL5 5 +#define SPL6 6 + +#define SPLPP 5 +#define SPLTTY 6 +#define SPLNI 6 + +#define IPLHI 8 +#define SPL7 IPLHI +#define SPLHI IPLHI + +#ifndef ASSEMBLER +extern int (*ivect[])(); +extern int iunit[]; +extern unsigned char intpri[]; +#endif ASSEMBLER + diff --git a/i386/pc/irq.h b/i386/pc/irq.h new file mode 100644 index 0000000..1f9da9a --- /dev/null +++ b/i386/pc/irq.h @@ -0,0 +1,49 @@ +/* + * 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 + */ +#ifndef _I386_PC_IRQ_H_ +#define _I386_PC_IRQ_H_ + +/* On normal PCs, there are always 16 IRQ lines. */ +#define IRQ_COUNT 16 + +/* Start of hardware interrupt vectors in the IDT. */ +#define IDT_IRQ_BASE 0x20 + +/* Variables storing the master and slave PIC interrupt vector base. */ +extern int irq_master_base, irq_slave_base; + +/* Routine called just after entering protected mode for the first time, + to set up the IRQ interrupt vectors in the protected-mode IDT. + It should initialize IDT entries irq_master_base through irq_master_base+7, + and irq_slave_base through irq_slave_base+7. */ +extern void idt_irq_init(void); + +/* Fill an IRQ gate in a CPU's IDT. + Always uses an interrupt gate; just set `access' to the privilege level. */ +#define fill_irq_gate(cpu, irq_num, entry, selector, access) \ + fill_idt_gate(cpu, (irq_num) < 8 \ + ? irq_master_base+(irq_num) \ + : irq_slave_base+(irq_num)-8, \ + entry, selector, ACC_INTR_GATE | (access)) + +#endif _I386_PC_IRQ_H_ diff --git a/i386/pc/irq_list.h b/i386/pc/irq_list.h new file mode 100644 index 0000000..bfd216e --- /dev/null +++ b/i386/pc/irq_list.h @@ -0,0 +1,43 @@ +/* + * 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 + */ + +/* This is just a handy file listing all the IRQ's on the PC, for whatever purpose... */ + +irq(master,0,0) +irq(master,1,1) +irq(master,2,2) +irq(master,3,3) +irq(master,4,4) +irq(master,5,5) +irq(master,6,6) +irq(master,7,7) + +irq(slave,0,8) +irq(slave,1,9) +irq(slave,2,10) +irq(slave,3,11) +irq(slave,4,12) +irq(slave,5,13) +irq(slave,6,14) +irq(slave,7,15) + diff --git a/i386/pc/pc_asm.sym b/i386/pc/pc_asm.sym new file mode 100644 index 0000000..e05677e --- /dev/null +++ b/i386/pc/pc_asm.sym @@ -0,0 +1,42 @@ +/* + * 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 "real.h" +#include "real_tss.h" + +offset real_call_data rcd eax +offset real_call_data rcd ebx +offset real_call_data rcd ecx +offset real_call_data rcd edx +offset real_call_data rcd esi +offset real_call_data rcd edi +offset real_call_data rcd ebp +offset real_call_data rcd flags +offset real_call_data rcd ds +offset real_call_data rcd es +offset real_call_data rcd fs +offset real_call_data rcd gs +size real_call_data rcd + +expr REAL_TSS_SIZE + diff --git a/i386/pc/phys_mem.h b/i386/pc/phys_mem.h new file mode 100644 index 0000000..558267c --- /dev/null +++ b/i386/pc/phys_mem.h @@ -0,0 +1,55 @@ +/* + * 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 + */ +/* + * PC-specific flag bits and priority values + * for the List Memory Manager (LMM) + * relevant for kernels managing physical memory. + */ +#ifndef _I386_PC_PHYS_MEM_H_ +#define _I386_PC_PHYS_MEM_H_ + +#include_next "phys_mem.h" + +/* <1MB memory is most precious, then <16MB memory, then high memory. + Assign priorities to each region accordingly + so that high memory will be used first when possible, + then 16MB memory, then 1MB memory. */ +#define LMM_PRI_1MB -2 +#define LMM_PRI_16MB -1 +#define LMM_PRI_HIGH 0 + +/* For memory <1MB, both LMMF_1MB and LMMF_16MB will be set. + For memory from 1MB to 16MB, only LMMF_16MB will be set. + For all memory higher than that, neither will be set. */ +#define LMMF_1MB 0x01 +#define LMMF_16MB 0x02 + + +/* Call one of these routines to add a chunk of physical memory found + to the malloc_lmm free list. + It assigns the appropriate flags and priorities to the region, + as defined above, breaking up the region if necessary. */ +void phys_mem_add(vm_offset_t min, vm_size_t size); +void i16_phys_mem_add(vm_offset_t min, vm_size_t size); + +#endif _I386_PC_PHYS_MEM_H_ diff --git a/i386/pc/phys_mem_add.c b/i386/pc/phys_mem_add.c new file mode 100644 index 0000000..79fd3ce --- /dev/null +++ b/i386/pc/phys_mem_add.c @@ -0,0 +1,62 @@ +/* + * 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_types.h> +#include <mach/lmm.h> +#include <malloc.h> + +#include "vm_param.h" +#include "phys_mem.h" + +/* Note that this routine takes _physical_ addresses, not virtual. */ +void phys_mem_add(vm_offset_t min, vm_size_t size) +{ + vm_offset_t max = min + size; + + /* Add the memory region with the proper flags and priority. */ + if (max <= 1*1024*1024) + { + lmm_add(&malloc_lmm, phystokv(min), size, + LMMF_1MB | LMMF_16MB, LMM_PRI_1MB); + } + else + { + if (min < 16*1024*1024) + { + vm_offset_t nmax = max; + if (nmax > 16*1024*1024) nmax = 16*1024*1024; + lmm_add(&malloc_lmm, phystokv(min), nmax - min, + LMMF_16MB, LMM_PRI_16MB); + } + if (max > 16*1024*1024) + { + vm_offset_t nmin = min; + if (nmin < 16*1024*1024) nmin = 16*1024*1024; + lmm_add(&malloc_lmm, phystokv(nmin), max - nmin, 0, 0); + } + } + + if (max > phys_mem_max) + phys_mem_max = max; +} + diff --git a/i386/pc/pic.c b/i386/pc/pic.c new file mode 100644 index 0000000..eaf7b56 --- /dev/null +++ b/i386/pc/pic.c @@ -0,0 +1,283 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* +Copyright (c) 1988,1989 Prime Computer, Inc. Natick, MA 01760 +All Rights Reserved. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and +without fee is hereby granted, provided that the above +copyright notice appears in all copies and that both the +copyright notice and this permission notice appear in +supporting documentation, and that the name of Prime +Computer, Inc. not be used in advertising or publicity +pertaining to distribution of the software without +specific, written prior permission. + +THIS SOFTWARE IS PROVIDED "AS IS", AND PRIME COMPUTER, +INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN +NO EVENT SHALL PRIME COMPUTER, INC. BE LIABLE FOR ANY +SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN ACTION OF CONTRACT, NEGLIGENCE, OR +OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#include <mach/machine/pio.h> + +#include <sys/types.h> + +#include "ipl.h" +#include "pic.h" + + +u_short pic_mask[SPLHI+1]; + +int curr_ipl; +u_short curr_pic_mask; + +u_short orig_pic_mask; +int orig_pic_mask_initialized; + +u_char intpri[NINTR]; + +/* +** picinit() - This routine +** * Establishes a table of interrupt vectors +** * Establishes a table of interrupt priority levels +** * Establishes a table of interrupt masks to be put +** in the PICs. +** * Establishes location of PICs in the system +** * Initialises them +** +** At this stage the interrupt functionality of this system should be +** coplete. +** +*/ + + +/* +** 1. First we form a table of PIC masks - rather then calling form_pic_mask() +** each time there is a change of interrupt level - we will form a table +** of pic masks, as there are only 7 interrupt priority levels. +** +** 2. The next thing we must do is to determine which of the PIC interrupt +** request lines have to be masked out, this is done by calling +** form_pic_mask() with a (int_lev) of zero, this will find all the +** interrupt lines that have priority 0, (ie to be ignored). +** Then we split this up for the master/slave PICs. +** +** 2. Initialise the PICs , master first, then the slave. +** All the register field definitions are described in pic_jh.h, also +** the settings of these fields for the various registers are selected. +** +*/ + +pic_init(int master_base, int slave_base) +{ + u_short PICM_OCW1, PICS_OCW1 ; + u_short PICM_OCW2, PICS_OCW2 ; + u_short PICM_OCW3, PICS_OCW3 ; + u_short i; + + if (!orig_pic_mask_initialized) + { + unsigned omaster, oslave; + + omaster = inb(MASTER_OCW); + PIC_DELAY(); + oslave = inb(SLAVES_OCW); + PIC_DELAY(); + + orig_pic_mask = omaster | (oslave << 8); + orig_pic_mask_initialized = 1; + } + + + /* + ** 1. Form pic mask table + */ + + form_pic_mask(); + + /* + ** 1a. Select current SPL. + */ + + curr_ipl = SPLHI; + curr_pic_mask = pic_mask[SPLHI]; + + /* + ** 3. Select options for each ICW and each OCW for each PIC. + */ + +#if 0 + PICM_ICW1 = (ICW_TEMPLATE | EDGE_TRIGGER | ADDR_INTRVL8 + | CASCADE_MODE | ICW4__NEEDED); + + PICS_ICW1 = (ICW_TEMPLATE | EDGE_TRIGGER | ADDR_INTRVL8 + | CASCADE_MODE | ICW4__NEEDED); + + PICM_ICW2 = master_base; + PICS_ICW2 = slave_base; + + PICM_ICW3 = ( SLAVE_ON_IR2 ); + PICS_ICW3 = ( I_AM_SLAVE_2 ); + + PICM_ICW4 = (SNF_MODE_DIS | NONBUFD_MODE | NRML_EOI_MOD + | I8086_EMM_MOD); + PICS_ICW4 = (SNF_MODE_DIS | NONBUFD_MODE | NRML_EOI_MOD + | I8086_EMM_MOD); +#endif + + PICM_OCW1 = (curr_pic_mask & 0x00FF); + PICS_OCW1 = ((curr_pic_mask & 0xFF00)>>8); + + PICM_OCW2 = NON_SPEC_EOI; + PICS_OCW2 = NON_SPEC_EOI; + + PICM_OCW3 = (OCW_TEMPLATE | READ_NEXT_RD | READ_IR_ONRD ); + PICS_OCW3 = (OCW_TEMPLATE | READ_NEXT_RD | READ_IR_ONRD ); + + + /* + ** 4. Initialise master - send commands to master PIC + */ + + outb ( MASTER_ICW, PICM_ICW1 ); + PIC_DELAY(); + outb ( MASTER_OCW, master_base ); + PIC_DELAY(); + outb ( MASTER_OCW, PICM_ICW3 ); + PIC_DELAY(); + outb ( MASTER_OCW, PICM_ICW4 ); + PIC_DELAY(); + +#if 0 + outb ( MASTER_OCW, PICM_MASK ); + PIC_DELAY(); + outb ( MASTER_ICW, PICM_OCW3 ); + PIC_DELAY(); +#endif + + /* + ** 5. Initialise slave - send commands to slave PIC + */ + + outb ( SLAVES_ICW, PICS_ICW1 ); + PIC_DELAY(); + outb ( SLAVES_OCW, slave_base ); + PIC_DELAY(); + outb ( SLAVES_OCW, PICS_ICW3 ); + PIC_DELAY(); + outb ( SLAVES_OCW, PICS_ICW4 ); + PIC_DELAY(); + +#if 0 + outb ( SLAVES_OCW, PICS_OCW1 ); + PIC_DELAY(); + outb ( SLAVES_ICW, PICS_OCW3 ); + PIC_DELAY(); + + /* + ** 6. Initialise interrupts + */ + outb ( MASTER_OCW, PICM_OCW1 ); + PIC_DELAY(); +#endif + + outb(MASTER_OCW, orig_pic_mask); + PIC_DELAY(); + outb(SLAVES_OCW, orig_pic_mask >> 8); + PIC_DELAY(); + +#if 0 + /* XXX */ + if (master_base != 8) + { + outb(0x21, 0xff); + PIC_DELAY(); + outb(0xa1, 0xff); + PIC_DELAY(); + } +#endif + + outb(MASTER_ICW, NON_SPEC_EOI); + PIC_DELAY(); + outb(SLAVES_ICW, NON_SPEC_EOI); + PIC_DELAY(); + + inb(0x60); + +} + +/* +** form_pic_mask(int_lvl) +** +** For a given interrupt priority level (int_lvl), this routine goes out +** and scans through the interrupt level table, and forms a mask based on the +** entries it finds there that have the same or lower interrupt priority level +** as (int_lvl). It returns a 16-bit mask which will have to be split up between +** the 2 pics. +** +*/ + +#define SLAVEMASK (0xFFFF ^ SLAVE_ON_IR2) +#define SLAVEACTV 0xFF00 + +form_pic_mask() +{ + unsigned short i, j, bit, mask; + + for (i=SPL0; i <= SPLHI; i++) { + for (j=0x00, bit=0x01, mask = 0; j < NINTR; j++, bit<<=1) + if (intpri[j] <= i) + mask |= bit; + + if ((mask & SLAVEACTV) != SLAVEACTV ) + mask &= SLAVEMASK; + + pic_mask[i] = mask; + } +} + +#if 0 + +intnull(unit_dev) +{ + printf("intnull(%d)\n", unit_dev); +} + +int prtnull_count = 0; +prtnull(unit) +{ + ++prtnull_count; +} + +#endif 0 diff --git a/i386/pc/pic.h b/i386/pc/pic.h new file mode 100644 index 0000000..51911cc --- /dev/null +++ b/i386/pc/pic.h @@ -0,0 +1,204 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* +Copyright (c) 1988,1989 Prime Computer, Inc. Natick, MA 01760 +All Rights Reserved. + +Permission to use, copy, modify, and distribute this +software and its documentation for any purpose and +without fee is hereby granted, provided that the above +copyright notice appears in all copies and that both the +copyright notice and this permission notice appear in +supporting documentation, and that the name of Prime +Computer, Inc. not be used in advertising or publicity +pertaining to distribution of the software without +specific, written prior permission. + +THIS SOFTWARE IS PROVIDED "AS IS", AND PRIME COMPUTER, +INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN +NO EVENT SHALL PRIME COMPUTER, INC. BE LIABLE FOR ANY +SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY +DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR +PROFITS, WHETHER IN ACTION OF CONTRACT, NEGLIGENCE, OR +OTHER TORTIOUS ACTION, ARISING OUR OF OR IN CONNECTION +WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ + +#ifndef _I386_PIC_H_ +#define _I386_PIC_H_ + +#include "irq.h" + +#define NINTR 0x10 +#define NPICS 0x02 + +/* +** The following are definitions used to locate the PICs in the system +*/ + +#define ADDR_PIC_BASE 0x20 +#define OFF_ICW 0x00 +#define OFF_OCW 0x01 +#define SIZE_PIC 0x80 + +#define MASTER_ICW (ADDR_PIC_BASE + OFF_ICW) +#define MASTER_OCW (ADDR_PIC_BASE + OFF_OCW) +#define SLAVES_ICW (ADDR_PIC_BASE + OFF_ICW + SIZE_PIC) +#define SLAVES_OCW (ADDR_PIC_BASE + OFF_OCW + SIZE_PIC) + +/* +** The following banks of definitions ICW1, ICW2, ICW3, and ICW4 are used +** to define the fields of the various ICWs for initialisation of the PICs +*/ + +/* +** ICW1 +*/ + +#define ICW_TEMPLATE 0x10 + +#define LEVL_TRIGGER 0x08 +#define EDGE_TRIGGER 0x00 +#define ADDR_INTRVL4 0x04 +#define ADDR_INTRVL8 0x00 +#define SINGLE__MODE 0x02 +#define CASCADE_MODE 0x00 +#define ICW4__NEEDED 0x01 +#define NO_ICW4_NEED 0x00 + +/* +** ICW2 +*/ + +#define PICM_VECTBASE IDT_IRQ_BASE +#define PICS_VECTBASE (PICM_VECTBASE + 0x08) + +/* +** ICW3 +*/ + +#define SLAVE_ON_IR0 0x01 +#define SLAVE_ON_IR1 0x02 +#define SLAVE_ON_IR2 0x04 +#define SLAVE_ON_IR3 0x08 +#define SLAVE_ON_IR4 0x10 +#define SLAVE_ON_IR5 0x20 +#define SLAVE_ON_IR6 0x40 +#define SLAVE_ON_IR7 0x80 + +#define I_AM_SLAVE_0 0x00 +#define I_AM_SLAVE_1 0x01 +#define I_AM_SLAVE_2 0x02 +#define I_AM_SLAVE_3 0x03 +#define I_AM_SLAVE_4 0x04 +#define I_AM_SLAVE_5 0x05 +#define I_AM_SLAVE_6 0x06 +#define I_AM_SLAVE_7 0x07 + +/* +** ICW4 +*/ + +#define SNF_MODE_ENA 0x10 +#define SNF_MODE_DIS 0x00 +#define BUFFERD_MODE 0x08 +#define NONBUFD_MODE 0x00 +#define AUTO_EOI_MOD 0x02 +#define NRML_EOI_MOD 0x00 +#define I8086_EMM_MOD 0x01 +#define SET_MCS_MODE 0x00 + +/* +** OCW1 +*/ + +#define PICM_MASK 0xFF +#define PICS_MASK 0xFF + +/* +** OCW2 +*/ + +#define NON_SPEC_EOI 0x20 +#define SPECIFIC_EOI 0x30 +#define ROT_NON_SPEC 0x50 +#define SET_ROT_AEOI 0x40 +#define RSET_ROTAEOI 0x00 +#define ROT_SPEC_EOI 0x70 +#define SET_PRIORITY 0x60 +#define NO_OPERATION 0x20 + +#define SEND_EOI_IR0 0x00 +#define SEND_EOI_IR1 0x01 +#define SEND_EOI_IR2 0x02 +#define SEND_EOI_IR3 0x03 +#define SEND_EOI_IR4 0x04 +#define SEND_EOI_IR5 0x05 +#define SEND_EOI_IR6 0x06 +#define SEND_EOI_IR7 0x07 + +/* +** OCW3 +*/ + +#define OCW_TEMPLATE 0x08 +#define SPECIAL_MASK 0x40 +#define MASK_MDE_SET 0x20 +#define MASK_MDE_RST 0x00 +#define POLL_COMMAND 0x04 +#define NO_POLL_CMND 0x00 +#define READ_NEXT_RD 0x02 +#define READ_IR_ONRD 0x00 +#define READ_IS_ONRD 0x01 + + +/* +** Standard PIC initialization values for PCs. +*/ +#define PICM_ICW1 (ICW_TEMPLATE | EDGE_TRIGGER | ADDR_INTRVL8 \ + | CASCADE_MODE | ICW4__NEEDED) +#define PICM_ICW3 (SLAVE_ON_IR2) +#define PICM_ICW4 (SNF_MODE_DIS | NONBUFD_MODE | NRML_EOI_MOD \ + | I8086_EMM_MOD) + +#define PICS_ICW1 (ICW_TEMPLATE | EDGE_TRIGGER | ADDR_INTRVL8 \ + | CASCADE_MODE | ICW4__NEEDED) +#define PICS_ICW3 (I_AM_SLAVE_2) +#define PICS_ICW4 (SNF_MODE_DIS | NONBUFD_MODE | NRML_EOI_MOD \ + | I8086_EMM_MOD) + +/* Some systems need a little bit of delay + while fiddling with PIC registers. */ +#ifndef ASSEMBLER +#define PIC_DELAY() asm volatile("jmp 1f; 1: jmp 1f; 1:") +#else +#define PIC_DELAY jmp 9f; 9: jmp 9f; 9: +#endif + + +#endif _I386_PIC_H_ diff --git a/i386/pc/putchar.c b/i386/pc/putchar.c new file mode 100644 index 0000000..d5b106c --- /dev/null +++ b/i386/pc/putchar.c @@ -0,0 +1,96 @@ +/* + * 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/eflags.h> + +#include "real.h" + +#ifndef ENABLE_IMMCONSOLE + +#include <rc.h> +int putchar(int c) +{ + + if (c == '\n') + putchar('\r'); + + { +#if RCLINE >= 0 + static int serial_inited = 0; + if (! serial_inited) { + init_serial(); + serial_inited = 1; + } + serial_putc(c); +#else + struct real_call_data rcd; + rcd.eax = 0x0e00 | (c & 0xff); + rcd.ebx = 0x07; + rcd.flags = 0; + real_int(0x10, &rcd); +#endif + } + + return 0; +} + +#else ENABLE_IMMCONSOLE + +void +putchar(unsigned char c) +{ + static int ofs = -1; + + if (ofs < 0) + { + ofs = 0; + putchar('\n'); + } + if (c == '\r') + { + ofs = 0; + } + else if (c == '\n') + { + bcopy(0xb8000+80*2, 0xb8000, 80*2*24); + bzero(0xb8000+80*2*24, 80*2); + ofs = 0; + } + else + { + volatile unsigned char *p; + + if (ofs >= 80) + { + putchar('\r'); + putchar('\n'); + } + + p = (void*)0xb8000 + 80*2*24 + ofs*2; + p[0] = c; + p[1] = 0x0f; + ofs++; + } +} + +#endif ENABLE_IMMCONSOLE diff --git a/i386/pc/real.h b/i386/pc/real.h new file mode 100644 index 0000000..4206231 --- /dev/null +++ b/i386/pc/real.h @@ -0,0 +1,60 @@ +/* + * 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_REAL_CALL_H_ +#define _I386_PC_REAL_CALL_H_ + +/* This structure happens to correspond to the DPMI real-call structure. */ +struct real_call_data +{ + unsigned edi; + unsigned esi; + unsigned ebp; + unsigned reserved; + unsigned ebx; + unsigned edx; + unsigned ecx; + unsigned eax; + unsigned short flags; + unsigned short es; + unsigned short ds; + unsigned short fs; + unsigned short gs; + unsigned short ip; + unsigned short cs; + unsigned short sp; + unsigned short ss; +}; + +/* Code segment we originally had when we started in real mode. */ +extern unsigned short real_cs; + +extern void (*real_int)(int intnum, struct real_call_data *rcd); +extern void (*real_exit)(int rc); + +#define real_call_data_init(rcd) \ + ({ (rcd)->flags = 0; \ + (rcd)->ss = 0; \ + (rcd)->sp = 0; \ + }) + +#endif /* _I386_PC_REAL_CALL_H_ */ diff --git a/i386/pc/real_tss.c b/i386/pc/real_tss.c new file mode 100644 index 0000000..745a611 --- /dev/null +++ b/i386/pc/real_tss.c @@ -0,0 +1,59 @@ +/* + * 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/tss.h> +#include <mach/machine/proc_reg.h> + +#include "cpu.h" +#include "real_tss.h" +#include "vm_param.h" +#include "config.h" + +#ifdef ENABLE_REAL_TSS + +static void real_tss_init() +{ + /* Only initialize once. */ + if (!real_tss.ss0) + { + /* Initialize the real-mode TSS. */ + real_tss.ss0 = KERNEL_DS; + real_tss.esp0 = get_esp(); + real_tss.io_bit_map_offset = sizeof(real_tss); + + /* Set the last byte in the I/O bitmap to all 1's. */ + ((unsigned char*)&real_tss)[REAL_TSS_SIZE] = 0xff; + } +} + +void +cpu_gdt_init_REAL_TSS(struct cpu *cpu) +{ + real_tss_init(); + + fill_gdt_descriptor(cpu, REAL_TSS, + kvtolin(&real_tss), REAL_TSS_SIZE-1, + ACC_PL_K|ACC_TSS, 0); +} + +#endif ENABLE_REAL_TSS diff --git a/i386/pc/real_tss.h b/i386/pc/real_tss.h new file mode 100644 index 0000000..2f89547 --- /dev/null +++ b/i386/pc/real_tss.h @@ -0,0 +1,34 @@ +/* + * 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_REAL_TSS_ +#define _I386_PC_REAL_TSS_ + +#include <mach/machine/tss.h> + +extern struct i386_tss real_tss; + +/* This size doesn't include the extra required 0xff byte + just past the end of the real IOPB. */ +#define REAL_TSS_SIZE (sizeof(real_tss)+65536/8) + +#endif _I386_PC_REAL_TSS_ diff --git a/i386/pc/real_tss_def.S b/i386/pc/real_tss_def.S new file mode 100644 index 0000000..1871250 --- /dev/null +++ b/i386/pc/real_tss_def.S @@ -0,0 +1,35 @@ +/* + * 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 "config.h" +#include "pc_asm.h" + +#ifdef ENABLE_REAL_TSS + + .data + .globl EXT(real_tss) + .comm EXT(real_tss),REAL_TSS_SIZE+1 + +#endif ENABLE_REAL_TSS diff --git a/i386/pc/rv86/config.h b/i386/pc/rv86/config.h new file mode 100644 index 0000000..5f971ce --- /dev/null +++ b/i386/pc/rv86/config.h @@ -0,0 +1,29 @@ +/* + * 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_next "config.h" + +#ifndef ENABLE_REAL_TSS +#define ENABLE_REAL_TSS +#endif + diff --git a/i386/pc/rv86/gdt_sels.h b/i386/pc/rv86/gdt_sels.h new file mode 100644 index 0000000..89a13c7 --- /dev/null +++ b/i386/pc/rv86/gdt_sels.h @@ -0,0 +1,60 @@ +/* + * 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_next "gdt_sels.h" + +/* This is a special TSS with a full IO bitmap + that allows access to all I/O ports in v86 mode. + It's used for making calls to the real-mode BIOS (or DOS). */ +gdt_sel(RV86_TSS) + +/* + * 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_next "gdt_sels.h" + +/* This is a special TSS with a full IO bitmap + that allows access to all I/O ports in v86 mode. + It's used for making calls to the real-mode BIOS (or DOS). */ +gdt_sel(RV86_TSS) + diff --git a/i386/pc/rv86/idt_irq_init.c b/i386/pc/rv86/idt_irq_init.c new file mode 100644 index 0000000..f46882a --- /dev/null +++ b/i386/pc/rv86/idt_irq_init.c @@ -0,0 +1,40 @@ +/* + * 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 "cpu.h" +#include "idt.h" + +void idt_irq_init() +{ + int i; + +#define irq(pic,picnum,irqnum) \ + { extern void rv86_reflect_irq##irqnum(); \ + fill_idt_gate(&cpu[0], irq_##pic##_base + picnum, \ + (vm_offset_t)rv86_reflect_irq##irqnum, KERNEL_CS, \ + ACC_PL_K|ACC_INTR_GATE); \ + } +#include "irq_list.h" +#undef irq +} + diff --git a/i386/pc/rv86/rv86_real_int.c b/i386/pc/rv86/rv86_real_int.c new file mode 100644 index 0000000..d9c35b6 --- /dev/null +++ b/i386/pc/rv86/rv86_real_int.c @@ -0,0 +1,276 @@ +/* + * 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 <mach/machine/far_ptr.h> +#include <mach/machine/eflags.h> + +#include "vm_param.h" +#include "real.h" +#include "real_tss.h" +#include "cpu.h" +#include "debug.h" + + +/* + + There seem to be three main ways to handle v86 mode: + + * The v86 environment is just an extension of the normal kernel environment: + you can switch to and from v86 mode just as you can change any other processor state. + You always keep running on the separate "logical" stack, + which is the kernel stack when running in protected mode, + or the user stack when running in v86 mode. + When in v86 mode, the "actual" kernel stack is just a stub + big enough to switch back to the "normal" kernel stack, + which was being used as the user stack while running in v86 mode. + Thus, v86 and protected-mode "segments" of stack data + can be interleaved together on the same logical stack. + + - To make a real int call from kernel pmode, + switch to v86 mode and execute an int instruction, + then switch back to protected mode. + + - To reflect an interrupt to v86 mode: + + > If the processor was running in v86 mode, + just adjust the kernel and user stacks + to emulate a real-mode interrupt, and return. + + > If the processor was running in pmode, + switch to v86 mode and re-trigger the interrupt + with a software int instruction. + + - To handle an interrupt in pmode: + + > If the processor was running in v86 mode, + switch from the stub stack to the user stack that was in use + (could be different from the stack we set originally, + because BIOS/DOS code might have switched stacks!), + call the interrupt handler, switch back, and return. + + > If the processor was running in pmode, + just call the interrupt handler and return. + + This method only works if the whole "kernel" is <64KB + and generally compatible with real-mode execution. + This is the model my DOS extender currently uses. + + One major disadvantage of this method + is that interrupt handlers can't run "general" protected-mode code, + such as typical code compiled by GCC. + This is because, if an interrupt occurs while in v86 mode, + the v86-mode ss:sp may point basically anywhere in the low 1MB, + and it therefore it can't be used directly as a pmode stack; + and the only other stack available is the miniscule stub stack. + Since "general" protected-mode code expects a full-size stack + with an SS equal to the normal protected-mode DS, + neither of these available stacks will suffice. + It is impossible to switch back to the original kernel stack + because arbitrary DOS or BIOS code might have switched from it + to a different stack somewhere else in the low 1MB, + and we have no way of telling where the SP was when that happened. + The upshot is that interrupt handlers must be extremely simple; + in MOSS, all they do is post a signal to "the process," + and return immediately without actually handling the interrupt. + + * The v86 environment is a separate "task" with its own user and kernel stacks; + you switch back and forth as if between multiple ordinary tasks, + the tasks can preempt each other, go idle waiting for events, etc. + + - To make a real int call from kernel pmode, + the task making the call essentially does a synchronous IPC to the v86 task. + If the v86 task is busy with another request or a reflected interrupt, + the calling task will go idle until the v86 task is available. + + - Reflecting an interrupt to v86 mode + basically amounts to sending a Unix-like "signal" to the v86 task: + + > If the processor was running in the v86 task, + just adjust the kernel and user stacks + to emulate a real-mode interrupt, and return. + + > If the processor was running in a protected-mode task + (or another v86-mode task), + post a signal to the v86 task, wake it up if it's asleep, + and invoke the scheduler to switch to the v86 task + if it has a higher priority than the currently running task. + + - To handle an interrupt in pmode, + just call the interrupt handler and return. + It doesn't matter whether the interrupt was from v86 or pmode, + because the kernel stacks look the same in either case. + + One big problem with this method is that if interrupts are to be handled in v86 mode, + all the typical problems of handling interrupts in user-mode tasks pop up. + In particular, an interrupt can now cause preemption, + so this will break an interruptible but nonpreemptible environment. + (The problem is not that the interrupted task is "preempted" + to switch temporarily to the v86 task to handle the interrupt; + the problem is that when the v86 task is done handling the interrupt, + the scheduler will be invoked and some task other than the interrupted task may be run.) + + Of course, this is undoubtedly the right solution + if that's the interrupt model the OS is using anyway + (i.e. if the OS already supports user-level protected-mode interrupts). + + * A bastardization of the two above approaches: + treat the v86 environment as a separate "task", + but a special one that doesn't behave at all like other tasks. + The v86 "task" in this case is more of an "interrupt co-stack" + that grows and shrinks alongside the normal interrupt stack + (or the current kernel stack, if interrupts are handled on the kernel stack). + Interrupts and real calls can cause switches between these two interrupt stacks, + but they can't cause preemption in the normal sense. + The route taken while building the stacks is exactly the opposite + the route taken while tearing it down. + + Now two "kernel stack pointers" have to be maintained all the time instead of one. + When running in protected mode: + + - The ESP register contains the pmode stack pointer. + - Some global variable contains the v86 stack pointer. + + When running in v86 mode: + + - The ESP register contains the v86 stack pointer. + (Note that BIOS/DOS code can switch stacks, + so at any given time it may point practically anywhere!) + - The current tss's esp0 contains the pmode stack pointer. + + Whenever a switch is made, a stack frame is placed on the new co-stack + indicating that the switch was performed. + + - To make a real int call from kernel pmode, + build a real-mode interrupt stack frame on the v86 interrupt stack, + build a v86-mode trap stack frame on the pmode stack, + set the tss's esp0 to point to the end of that stack frame, + and iret from it. + Then when the magic "done-with-real-call" int instruction is hit, + the pmode interrupt handler will see it + and know to simply destroy the v86 trap stack on the pmode stack. + + - Handling an interrupt can always be thought of as going "through" pmode: + switching from the v86 stack to the pmode stack + if the processor was in v86 mode when the interrupt was taken, + and switching from the pmode stack back to the v86 stack as described above + if the interrupt is to be reflected to v86 mode. + + Of course, optimized paths are possible: + + - To reflect an interrupt to v86 mode: + + > If the processor was running in v86 mode, + just adjust the kernel and user stack frames and return. + + > If the processor was running in pmode, + do as described above for explicit real int calls. + + - To handle an interrupt in pmode: + + > If the processor was running in v86 mode, + switch to the pmode stack, + stash the old v86 stack pointer variable on the pmode stack, + and set the v86 stack pointer variable to the new location. + Call the interrupt handler, + then tear down everything and return to v86 mode. + + Observation: + In the first and third models, + explicit real int calls are entirely symmetrical + to hardware interrupts from pmode to v86 mode. + This is valid because of the interruptible but nonpreemptible model: + no scheduling is involved, and the stack(s) will always be torn down + in exactly the opposite order in which they were built up. + In the second model, + explicit real calls are quite different, + because the BIOS is interruptible but nonpreemptible: + you can reflect an interrupt into the v86 task at any time, + but you can only make an explicit request to that task when it's ready + (i.e. no other requests or interrupts are outstanding). + +*/ + + + +#define RV86_USTACK_SIZE 1024 + +vm_offset_t rv86_ustack_pa; +vm_offset_t rv86_return_int_pa; +struct far_pointer_32 rv86_usp; +struct far_pointer_16 rv86_rp; + +void rv86_real_int(int intnum, struct real_call_data *rcd) +{ + unsigned short old_tr; + unsigned int old_eflags; + + /* If this is the first time this routine is being called, + initialize the kernel stack. */ + if (!rv86_ustack_pa) + { + rv86_ustack_pa = 0xa0000 - RV86_USTACK_SIZE; /* XXX */ + + assert(rv86_ustack_pa < 0x100000); + + /* Use the top two bytes of the ustack for an 'int $0xff' instruction. */ + rv86_return_int_pa = rv86_ustack_pa + RV86_USTACK_SIZE - 2; + *(short*)phystokv(rv86_return_int_pa) = 0xffcd; + + /* Set up the v86 stack pointer. */ + rv86_usp.seg = rv86_rp.seg = rv86_ustack_pa >> 4; + rv86_usp.ofs = rv86_rp.ofs = (rv86_ustack_pa & 0xf) + RV86_USTACK_SIZE - 2; + + /* Pre-allocate a real-mode interrupt stack frame. */ + rv86_usp.ofs -= 6; + } + + /* Make sure interrupts are disabled. */ + old_eflags = get_eflags(); + + /* Switch to the TSS to use in v86 mode. */ + old_tr = get_tr(); + cpu[0].tables.gdt[REAL_TSS_IDX].access &= ~ACC_TSS_BUSY; + set_tr(REAL_TSS); + + asm volatile(" + pushl %%ebp + pushl %%eax + call rv86_real_int_asm + popl %%eax + popl %%ebp + " : + : "a" (rcd), "S" (intnum) + : "eax", "ebx", "ecx", "edx", "esi", "edi"); + + /* Switch to the original TSS. */ + cpu[0].tables.gdt[old_tr/8].access &= ~ACC_TSS_BUSY; + set_tr(old_tr); + + /* Restore the original processor flags. */ + set_eflags(old_eflags); +} + +void (*real_int)(int intnum, struct real_call_data *rcd) = rv86_real_int; + diff --git a/i386/pc/rv86/rv86_real_int_asm.S b/i386/pc/rv86/rv86_real_int_asm.S new file mode 100644 index 0000000..54b1b9b --- /dev/null +++ b/i386/pc/rv86/rv86_real_int_asm.S @@ -0,0 +1,119 @@ +/* + * 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/asm.h> +#include <mach/machine/eflags.h> + +#include "trap.h" +#include "i386_asm.h" +#include "pc_asm.h" +#include "trap_asm.h" + + .text + .globl rv86_real_int_asm +rv86_real_int_asm: + + /* Stash our protected-mode stack pointer. */ + movl %esp,EXT(real_tss)+TSS_ESP0 + + /* Load the linear/physical-address data segment into ES, + for easy access to real-mode memory. */ + movl $LINEAR_DS,%edx + movw %dx,%es + + /* Find the physical address of the real-mode interrupt stack (es:ebx). + A 6-byte stack frame has already been allocated on it. */ + movl EXT(rv86_usp)+4,%ebx + shll $4,%ebx + addl EXT(rv86_usp),%ebx + + /* Store the magic return pointer into the real-mode interrupt stack frame. */ + movl EXT(rv86_rp),%edx + movl %edx,%es:(%ebx) + movw RCD_FLAGS(%eax),%dx + movw %dx,%es:4(%ebx) + + /* Find the address of the real mode interrupt vector (es:esi). */ + shll $2,%esi + + /* Build the v86 trap frame. */ + xorl %edx,%edx + movw RCD_GS(%eax),%dx + pushl %edx + movw RCD_FS(%eax),%dx + pushl %edx + movw RCD_DS(%eax),%dx + pushl %edx + movw RCD_ES(%eax),%dx + pushl %edx + pushl EXT(rv86_usp)+4 + pushl EXT(rv86_usp) + movl $EFL_VM+EFL_IOPL_USER,%ecx + orw RCD_FLAGS(%eax),%cx + andl $-1-EFL_IF-EFL_TF,%ecx + pushl %ecx + movw %es:2(%esi),%edx + pushl %edx + movw %es:(%esi),%edx + pushl %edx + + /* Load the requested register state. */ + movl RCD_EDI(%eax),%edi + movl RCD_ESI(%eax),%esi + movl RCD_EBP(%eax),%ebp + movl RCD_EBX(%eax),%ebx + movl RCD_EDX(%eax),%edx + movl RCD_ECX(%eax),%ecx + movl RCD_EAX(%eax),%eax + + /* Drop into v86 mode. */ + iret + +ENTRY(rv86_return) + + /* Restore the kernel segment registers. */ + movw %ss,%ax + movw %ax,%ds + movw %ax,%es + + /* Retrieve the real_call_data pointer from rv86_real_int_asm's stack frame. */ + movl TR_V86SIZE+4(%esp),%eax + + /* Stash the final register state. */ + movl TR_EDI(%esp),%edx; movl %edx,RCD_EDI(%eax) + movl TR_ESI(%esp),%edx; movl %edx,RCD_ESI(%eax) + movl TR_EBP(%esp),%edx; movl %edx,RCD_EBP(%eax) + movl TR_EBX(%esp),%edx; movl %edx,RCD_EBX(%eax) + movl TR_EDX(%esp),%edx; movl %edx,RCD_EDX(%eax) + movl TR_ECX(%esp),%edx; movl %edx,RCD_ECX(%eax) + movl TR_EAX(%esp),%edx; movl %edx,RCD_EAX(%eax) + movl TR_EFLAGS(%esp),%edx; movw %dx,RCD_FLAGS(%eax) + movl TR_V86_ES(%esp),%edx; movw %dx,RCD_ES(%eax) + movl TR_V86_DS(%esp),%edx; movw %dx,RCD_DS(%eax) + movl TR_V86_FS(%esp),%edx; movw %dx,RCD_FS(%eax) + movl TR_V86_GS(%esp),%edx; movw %dx,RCD_GS(%eax) + + /* Return from the call to rv86_real_int_asm. */ + lea TR_V86SIZE(%esp),%esp + ret + diff --git a/i386/pc/rv86/rv86_reflect_irq.S b/i386/pc/rv86/rv86_reflect_irq.S new file mode 100644 index 0000000..5d68fae --- /dev/null +++ b/i386/pc/rv86/rv86_reflect_irq.S @@ -0,0 +1,113 @@ +/* + * 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/asm.h> +#include <mach/machine/eflags.h> + +#include "trap.h" +#include "trap_asm.h" +#include "pc_asm.h" +#include "i386_asm.h" + +/* + * Define a set of interrupt handlers to reflect interrupts to v86 mode. + */ + + .text + +#define master_base 0x08 +#define slave_base 0x70 + +#define irq(pic,picnum,irqnum) \ +ENTRY(rv86_reflect_irq##irqnum) ;\ + pushl $pic##_base+picnum ;\ + pushl $0x80000000+irqnum /* (for debug) */ ;\ + jmp allintrs + +#include "irq_list.h" + + +allintrs: + pusha + pushl %ds + pushl %es + pushl %fs + pushl %gs + + /* Load the normal kernel segment registers. */ + movw %ss,%ax + movw %ax,%ds + movw %ax,%es + + /* See if we came from v86 mode. */ + testl $EFL_VM,TR_EFLAGS(%esp) + jnz int_from_v86 + + movl TR_ERR(%esp),%eax + pushl $dummy_rcd + pushl %eax + call EXT(rv86_real_int) + addl $2*4,%esp + + popl %gs + popl %fs + popl %es + popl %ds + popa + addl $2*4,%esp + iret + +int_from_v86: + + /* Save the v86 stack pointer before handling the interrupt. + We need this in order to handle recursive reflected interrupts + possibly interspersed with protected-mode interrupts. */ + movl EXT(rv86_usp),%esi + movl EXT(rv86_usp)+4,%edi + movl EXT(real_tss)+TSS_ESP0,%ebx + + movl TR_ESP(%esp),%eax + subw $6,%ax /* allocate a real-mode interrupt stack frame. */ + movl %eax,EXT(rv86_usp) + movl TR_SS(%esp),%eax + movw %ax,EXT(rv86_usp)+4 + + movl TR_ERR(%esp),%eax + pushl $dummy_rcd + pushl %eax + call EXT(rv86_real_int) + addl $2*4,%esp + + movl %esi,EXT(rv86_usp) + movl %edi,EXT(rv86_usp)+4 + movl %ebx,EXT(real_tss)+TSS_ESP0 + + addl $4*4,%esp + popa + addl $2*4,%esp + iret + + /* Dummy real_call_data structure (always all zero) + to use when reflecting hardware interrupts. */ + .comm dummy_rcd,RCD_SIZE + diff --git a/i386/pc/rv86/rv86_trap_handler.S b/i386/pc/rv86/rv86_trap_handler.S new file mode 100644 index 0000000..793f6b6 --- /dev/null +++ b/i386/pc/rv86/rv86_trap_handler.S @@ -0,0 +1,167 @@ +/* + * 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 <mach/machine/eflags.h> + +#include "i386_asm.h" +#include "trap.h" +#include "trap_asm.h" + + .text + +ENTRY(rv86_trap_handler) + cmpl $T_GENERAL_PROTECTION,TR_TRAPNO(%esp) + jz gpf_from_v86 + + UNEXPECTED_TRAP + +gpf_from_v86: + + /* Load the linear/physical-address data segment, + for easy access to real-mode memory. */ + movl $LINEAR_DS,%eax + movw %ax,%ds + + /* Find the physical address of the trapping instruction (ebx). */ + movzwl TR_CS(%esp),%ebx + shll $4,%ebx + addl TR_EIP(%esp),%ebx + + /* See if we're just trying to get out of v86 mode. */ + cmpl %ss:EXT(rv86_return_int_pa),%ebx + je EXT(rv86_return) + + /* Check the instruction (al). */ + movb (%ebx),%al + cmpb $0xcd,%al + je gpf_int_n + + UNEXPECTED_TRAP + + +gpf_int_n: + + /* Bump the ip past the int instruction. */ + addw $2,TR_EIP(%esp) + + /* Find the real mode interrupt vector number (esi). */ + movzbl 1(%ebx),%esi + + /* See if it's a copy-extended-memory interrupt request; + if so, just handle it here. */ + cmpl $0x15,%esi + jne 1f + cmpb $0x87,TR_EAX+1(%esp) + je copy_ext_mem +1: + + /* XXX The stuff down here is essentially the same as in moss. */ + +reflect_v86_intr: + + /* Find the address of the real mode interrupt vector (esi). */ + shll $2,%esi + + /* Make room for the real-mode interrupt stack frame. */ + subw $6,TR_ESP(%esp) + + /* Find the physical address of the v86 stack (ebx). */ + movzwl TR_SS(%esp),%ebx + shll $4,%ebx + addl TR_ESP(%esp),%ebx + + /* Store the return information into the v86 stack frame. */ + movl TR_EIP(%esp),%eax + movw %ax,(%ebx) + movl TR_CS(%esp),%eax + movw %ax,2(%ebx) + movl TR_EFLAGS(%esp),%eax + movw %ax,4(%ebx) + + /* Find the real-mode interrupt vector to invoke, + and set up the real_call_thread's kernel stack frame + to point to it. */ + movl (%esi),%eax + movw %ax,TR_EIP(%esp) + shrl $16,%eax + movw %ax,TR_CS(%esp) + andl $-1-EFL_IF-EFL_TF,TR_EFLAGS(%esp) + + /* Restore saved state and return. */ + addl $4*4,%esp + popa + addl $4*2,%esp + iret + + + +/* We intercepted a copy-extended-memory software interrupt + (int 0x15 function 0x87). + This is used by HIMEM.SYS, for example, to manage extended memory. + The BIOS's routine isn't going to work in v86 mode, + so do it ourselves. */ +copy_ext_mem: + + /* Find the parameter block provided by the caller (ebx). */ + movzwl TR_V86_ES(%esp),%ebx + movzwl TR_ESI(%esp),%eax + shll $4,%ebx + addl %eax,%ebx + + /* Source address (esi). */ + movl 0x12(%ebx),%esi + andl $0x00ffffff,%esi + + /* Destination address (edi). */ + movl 0x1a(%ebx),%edi + andl $0x00ffffff,%edi + + /* Number of bytes (ecx). */ + movzwl TR_ECX(%esp),%ecx + addl %ecx,%ecx + + /* Use the standard i386 bcopy routine to copy the data. + This assumes it's "friendly" in its use of segment registers + (i.e. always uses ss for stack data and ds/es for the data to copy). + The bcopy is simple enough that this should always be true. */ + movw %ds,%ax + movw %ax,%es + cld + pushl %ecx + pushl %edi + pushl %esi + call EXT(bcopy) + addl $3*4,%esp + + /* Clear the carry flag to indicate that the copy was successful. + AH is also cleared, below. */ + andl $-1-EFL_CF,TR_EFLAGS(%esp) + + /* Restore saved state and return. */ + addl $4*4,%esp + popa + xorb %ah,%ah + addl $4*2,%esp + iret + diff --git a/i386/pc/rv86/trap_handler.S b/i386/pc/rv86/trap_handler.S new file mode 100644 index 0000000..99254ee --- /dev/null +++ b/i386/pc/rv86/trap_handler.S @@ -0,0 +1,39 @@ +/* + * 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 <mach/machine/eflags.h> + +#include "trap.h" +#include "trap_asm.h" + + .text + +ENTRY(trap_handler) + + /* See if we came from v86 mode. */ + testl $EFL_VM,TR_EFLAGS(%esp) + jnz EXT(rv86_trap_handler) + + UNEXPECTED_TRAP + |