summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/aic7xxx/aic7xxx.seq26
-rw-r--r--sys/dev/aic7xxx/aicasm.c482
-rw-r--r--sys/dev/aic7xxx/aicasm.h68
-rw-r--r--sys/dev/aic7xxx/aicasm_gram.y1304
-rw-r--r--sys/dev/aic7xxx/aicasm_scan.l243
-rw-r--r--sys/dev/aic7xxx/aicasm_symbol.c451
-rw-r--r--sys/dev/aic7xxx/aicasm_symbol.h144
-rw-r--r--sys/i386/include/asm.h201
-rw-r--r--sys/i386/include/vmparam.h5
-rw-r--r--sys/i386/scsi/aic7xxx.c26
-rw-r--r--sys/miscfs/procfs/procfs_map.c6
-rw-r--r--sys/scsi/scsi_base.c4
-rw-r--r--sys/vm/vm_extern.h3
-rw-r--r--sys/vm/vm_fault.c73
-rw-r--r--sys/vm/vm_glue.c18
-rw-r--r--sys/vm/vm_kern.c32
-rw-r--r--sys/vm/vm_map.c413
-rw-r--r--sys/vm/vm_map.h24
-rw-r--r--sys/vm/vm_meter.c4
-rw-r--r--sys/vm/vm_mmap.c33
-rw-r--r--sys/vm/vm_object.c72
-rw-r--r--sys/vm/vm_page.c55
-rw-r--r--sys/vm/vm_pageout.c26
-rw-r--r--sys/vm/vm_pageout.h35
-rw-r--r--sys/vm/vnode_pager.c4
25 files changed, 541 insertions, 3211 deletions
diff --git a/sys/dev/aic7xxx/aic7xxx.seq b/sys/dev/aic7xxx/aic7xxx.seq
index 5077ef0092d0f..572586588dd99 100644
--- a/sys/dev/aic7xxx/aic7xxx.seq
+++ b/sys/dev/aic7xxx/aic7xxx.seq
@@ -1039,7 +1039,18 @@ dma_scb:
mov DFCNTRL, DMAPARAMS;
test DMAPARAMS, DIRECTION jnz dma_scb_fromhost;
/* Fill it with the SCB data */
- call copy_scb_tofifo;
+copy_scb_tofifo:
+ mvi SINDEX, SCB_CONTROL;
+ add A, 28, SINDEX;
+copy_scb_tofifo_loop:
+ mov DFDAT,SINDIR;
+ mov DFDAT,SINDIR;
+ mov DFDAT,SINDIR;
+ mov DFDAT,SINDIR;
+ mov DFDAT,SINDIR;
+ mov DFDAT,SINDIR;
+ mov DFDAT,SINDIR;
+ cmp SINDEX, A jne copy_scb_tofifo_loop;
or DFCNTRL, HDMAEN|FIFOFLUSH;
dma_scb_fromhost:
call dma_finish;
@@ -1060,19 +1071,6 @@ dfdat_in_7_continued:
mov DINDIR,DFDAT;
mov DINDIR,DFDAT ret;
-copy_scb_tofifo:
- mvi SCB_CONTROL call dfdat_out_7;
- call dfdat_out_7;
- call dfdat_out_7;
-dfdat_out_7:
- mov DFDAT,SINDIR;
- mov DFDAT,SINDIR;
- mov DFDAT,SINDIR;
- mov DFDAT,SINDIR;
- mov DFDAT,SINDIR;
- mov DFDAT,SINDIR;
- mov DFDAT,SINDIR ret;
-
/*
* Wait for DMA from host memory to data FIFO to complete, then disable
* DMA and wait for it to acknowledge that it's off.
diff --git a/sys/dev/aic7xxx/aicasm.c b/sys/dev/aic7xxx/aicasm.c
deleted file mode 100644
index 4251af1a383ea..0000000000000
--- a/sys/dev/aic7xxx/aicasm.c
+++ /dev/null
@@ -1,482 +0,0 @@
-/*
- * Aic7xxx SCSI host adapter firmware asssembler
- *
- * Copyright (c) 1997 Justin T. Gibbs.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: aic7xxx_asm.c,v 1.12.6.1 1997/03/16 07:21:30 gibbs Exp $
- */
-#include <sys/types.h>
-#include <sys/mman.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-#include <unistd.h>
-
-#include "aic7xxx_asm.h"
-#include "symbol.h"
-#include "sequencer.h"
-
-static void usage __P((void));
-static void back_patch __P((void));
-static void output_code __P((FILE *ofile));
-static void output_listing __P((FILE *listfile, char *ifilename,
- char *options));
-static struct patch *next_patch __P((struct patch *cur_patch, int options,
- int instrptr));
-
-struct path_list search_path;
-int includes_search_curdir;
-char *appname;
-FILE *ofile;
-char *ofilename;
-
-static STAILQ_HEAD(,instruction) seq_program;
-static STAILQ_HEAD(, patch) patch_list;
-symlist_t patch_options;
-
-#if DEBUG
-extern int yy_flex_debug;
-extern int yydebug;
-#endif
-extern FILE *yyin;
-extern int yyparse __P((void));
-
-int
-main(argc, argv)
- int argc;
- char *argv[];
-{
- extern char *optarg;
- extern int optind;
- int ch;
- int retval;
- char *inputfilename;
- char *regfilename;
- FILE *regfile;
- char *listfilename;
- FILE *listfile;
- char *options;
-
- SLIST_INIT(&search_path);
- STAILQ_INIT(&seq_program);
- STAILQ_INIT(&patch_list);
- SLIST_INIT(&patch_options);
- includes_search_curdir = 1;
- appname = *argv;
- regfile = NULL;
- listfile = NULL;
- options = NULL;
-#if DEBUG
- yy_flex_debug = 0;
-#endif
- while ((ch = getopt(argc, argv, "d:l:n:o:r:I:O:")) != EOF) {
- switch(ch) {
- case 'd':
-#if DEBUG
- if (strcmp(optarg, "s") == 0)
- yy_flex_debug = 1;
- else if (strcmp(optarg, "p") == 0)
- yydebug = 1;
-#else
- stop("-d: Assembler not built with debugging "
- "information", EX_SOFTWARE);
-#endif
- break;
- case 'l':
- /* Create a program listing */
- if ((listfile = fopen(optarg, "w")) == NULL) {
- perror(optarg);
- stop(NULL, EX_CANTCREAT);
- }
- listfilename = optarg;
- break;
- case 'n':
- /* Don't complain about the -nostdinc directrive */
- if (strcmp(optarg, "ostdinc")) {
- fprintf(stderr, "%s: Unknown option -%c%s\n",
- appname, ch, optarg);
- usage();
- /* NOTREACHED */
- }
- break;
- case 'o':
- if ((ofile = fopen(optarg, "w")) == NULL) {
- perror(optarg);
- stop(NULL, EX_CANTCREAT);
- }
- ofilename = optarg;
- break;
- case 'O':
- /* Patches to include in the listing */
- options = optarg;
- break;
- case 'r':
- if ((regfile = fopen(optarg, "w")) == NULL) {
- perror(optarg);
- stop(NULL, EX_CANTCREAT);
- }
- regfilename = optarg;
- break;
- case 'I':
- {
- path_entry_t include_dir;
-
- if (strcmp(optarg, "-") == 0) {
- if (includes_search_curdir == 0) {
- fprintf(stderr, "%s: Warning - '-I-' "
- "specified multiple "
- "times\n", appname);
- }
- includes_search_curdir = 0;
- for (include_dir = search_path.slh_first;
- include_dir != NULL;
- include_dir = include_dir->links.sle_next)
- /*
- * All entries before a '-I-' only
- * apply to includes specified with
- * quotes instead of "<>".
- */
- include_dir->quoted_includes_only = 1;
- } else {
- include_dir =
- (path_entry_t)malloc(sizeof(*include_dir));
- if (include_dir == NULL) {
- perror(optarg);
- stop(NULL, EX_OSERR);
- }
- include_dir->directory = strdup(optarg);
- if (include_dir->directory == NULL) {
- perror(optarg);
- stop(NULL, EX_OSERR);
- }
- include_dir->quoted_includes_only = 0;
- SLIST_INSERT_HEAD(&search_path, include_dir,
- links);
- }
- break;
- }
- case '?':
- default:
- usage();
- /* NOTREACHED */
- }
- }
- argc -= optind;
- argv += optind;
-
- if (argc != 1) {
- fprintf(stderr, "%s: No input file specifiled\n", appname);
- usage();
- /* NOTREACHED */
- }
-
- symtable_open();
- inputfilename = *argv;
- include_file(*argv, SOURCE_FILE);
- retval = yyparse();
- if (retval == 0) {
- back_patch();
- if (ofile != NULL)
- output_code(ofile);
- if (regfile != NULL)
- symtable_dump(regfile);
- if (listfile != NULL)
- output_listing(listfile, inputfilename, options);
- }
-
- stop(NULL, 0);
- /* NOTREACHED */
- return (0);
-}
-
-static void
-usage()
-{
-
- (void)fprintf(stderr,
-"usage: %-16s [-nostdinc] [-I-] [-I directory] [-o output_file]
- [-r register_output_file] [-l program_list_file]
- [-O option_name[|options_name2]] input_file\n",
- appname);
- exit(EX_USAGE);
-}
-
-static void
-back_patch()
-{
- struct instruction *cur_instr;
-
- for(cur_instr = seq_program.stqh_first;
- cur_instr != NULL;
- cur_instr = cur_instr->links.stqe_next) {
- if (cur_instr->patch_label != NULL) {
- struct ins_format3 *f3_instr;
- u_int address;
-
- if (cur_instr->patch_label->type != LABEL) {
- char buf[255];
-
- snprintf(buf, sizeof(buf),
- "Undefined label %s",
- cur_instr->patch_label->name);
- stop(buf, EX_DATAERR);
- /* NOTREACHED */
- }
- f3_instr = &cur_instr->format.format3;
- address = ((f3_instr->opcode_addr & ADDR_HIGH_BIT) << 8)
- | f3_instr->address;
- address += cur_instr->patch_label->info.linfo->address;
- f3_instr->opcode_addr &= ~ADDR_HIGH_BIT;
- f3_instr->opcode_addr |= (address >> 8) & ADDR_HIGH_BIT;
- f3_instr->address = address & 0xFF;
- }
- }
-}
-
-static void
-output_code(ofile)
- FILE *ofile;
-{
- struct instruction *cur_instr;
- patch_t *cur_patch;
- symbol_node_t *cur_node;
- int instrcount;
-
- instrcount = 0;
- fprintf(ofile,
-"/*
- * DO NOT EDIT - This file is automatically generated.
- */\n");
-
- fprintf(ofile, "static u_int8_t seqprog[] = {\n");
- for(cur_instr = seq_program.stqh_first;
- cur_instr != NULL;
- cur_instr = cur_instr->links.stqe_next) {
- fprintf(ofile, "\t0x%02x, 0x%02x, 0x%02x, 0x%02x,\n",
- cur_instr->format.bytes[0],
- cur_instr->format.bytes[1],
- cur_instr->format.bytes[2],
- cur_instr->format.bytes[3]);
- instrcount++;
- }
- fprintf(ofile, "};\n");
-
- /*
- * Output the patch list, option definitions first.
- */
- for(cur_node = patch_options.slh_first;
- cur_node != NULL;
- cur_node = cur_node->links.sle_next) {
- fprintf(ofile, "#define\t%-16s\t0x%x\n", cur_node->symbol->name,
- cur_node->symbol->info.condinfo->value);
- }
-
- fprintf(ofile,
-"struct patch {
- int options;
- int negative;
- int begin;
- int end;
-} patches[] = {\n");
-
- for(cur_patch = patch_list.stqh_first;
- cur_patch != NULL;
- cur_patch = cur_patch->links.stqe_next)
-
- fprintf(ofile, "\t{ 0x%08x, %d, 0x%03x, 0x%03x },\n",
- cur_patch->options, cur_patch->negative, cur_patch->begin,
- cur_patch->end);
-
- fprintf(ofile, "\t{ 0x%08x, %d, 0x%03x, 0x%03x }\n};\n",
- 0, 0, 0, 0);
-
- fprintf(stderr, "%s: %d instructions used\n", appname, instrcount);
-}
-
-void
-output_listing(listfile, ifilename, patches)
- FILE *listfile;
- char *ifilename;
- char *patches;
-{
- FILE *ifile;
- int line;
- struct instruction *cur_instr;
- int instrcount;
- int instrptr;
- char buf[1024];
- patch_t *cur_patch;
- char *option_spec;
- int options;
-
- instrcount = 0;
- instrptr = 0;
- line = 1;
- options = 1; /* All code outside of patch blocks */
- if ((ifile = fopen(ifilename, "r")) == NULL) {
- perror(ifilename);
- stop(NULL, EX_DATAERR);
- }
-
- /*
- * Determine which options to apply to this listing.
- */
- while ((option_spec = strsep(&patches, "|")) != NULL) {
- symbol_t *symbol;
-
- symbol = symtable_get(option_spec);
- if (symbol->type != CONDITIONAL) {
- stop("Invalid option specified in patch list for "
- "program listing", EX_USAGE);
- /* NOTREACHED */
- }
- options |= symbol->info.condinfo->value;
- }
-
- cur_patch = patch_list.stqh_first;
- for(cur_instr = seq_program.stqh_first;
- cur_instr != NULL;
- cur_instr = cur_instr->links.stqe_next,instrcount++) {
-
- cur_patch = next_patch(cur_patch, options, instrcount);
- if (cur_patch
- && cur_patch->begin <= instrcount
- && cur_patch->end > instrcount)
- /* Don't count this instruction as it is in a patch
- * that was removed.
- */
- continue;
-
- while (line < cur_instr->srcline) {
- fgets(buf, sizeof(buf), ifile);
- fprintf(listfile, "\t\t%s", buf);
- line++;
- }
- fprintf(listfile, "%03x %02x%02x%02x%02x", instrptr,
- cur_instr->format.bytes[0],
- cur_instr->format.bytes[1],
- cur_instr->format.bytes[2],
- cur_instr->format.bytes[3]);
- fgets(buf, sizeof(buf), ifile);
- fprintf(listfile, "\t%s", buf);
- line++;
- instrptr++;
- }
- /* Dump the remainder of the file */
- while(fgets(buf, sizeof(buf), ifile) != NULL)
- fprintf(listfile, "\t\t%s", buf);
-
- fclose(ifile);
-}
-
-static struct patch *
-next_patch(cur_patch, options, instrptr)
- struct patch *cur_patch;
- int options;
- int instrptr;
-{
- while(cur_patch != NULL) {
- if (((cur_patch->options & options) != 0
- && cur_patch->negative == FALSE)
- || ((cur_patch->options & options) == 0
- && cur_patch->negative == TRUE)
- || (instrptr >= cur_patch->end)) {
- /*
- * Either we want to keep this section of code,
- * or we have consumed this patch. Skip to the
- * next patch.
- */
- cur_patch = cur_patch->links.stqe_next;
- } else
- /* Found an okay patch */
- break;
- }
- return (cur_patch);
-}
-
-/*
- * Print out error information if appropriate, and clean up before
- * terminating the program.
- */
-void
-stop(string, err_code)
- const char *string;
- int err_code;
-{
- if (string != NULL) {
- fprintf(stderr, "%s: ", appname);
- if (yyfilename != NULL) {
- fprintf(stderr, "Stopped at file %s, line %d - ",
- yyfilename, yylineno);
- }
- fprintf(stderr, "%s\n", string);
- }
-
- if (ofile != NULL) {
- fclose(ofile);
- if (err_code != 0) {
- fprintf(stderr, "%s: Removing %s due to error\n",
- appname, ofilename);
- unlink(ofilename);
- }
- }
-
- symlist_free(&patch_options);
- symtable_close();
-
- exit(err_code);
-}
-
-struct instruction *
-seq_alloc()
-{
- struct instruction *new_instr;
-
- new_instr = (struct instruction *)malloc(sizeof(struct instruction));
- if (new_instr == NULL)
- stop("Unable to malloc instruction object", EX_SOFTWARE);
- memset(new_instr, 0, sizeof(*new_instr));
- STAILQ_INSERT_TAIL(&seq_program, new_instr, links);
- new_instr->srcline = yylineno;
- return new_instr;
-}
-
-patch_t *
-patch_alloc()
-{
- patch_t *new_patch;
-
- new_patch = (patch_t *)malloc(sizeof(patch_t));
- if (new_patch == NULL)
- stop("Unable to malloc patch object", EX_SOFTWARE);
- memset(new_patch, 0, sizeof(*new_patch));
- STAILQ_INSERT_TAIL(&patch_list, new_patch, links);
- return new_patch;
-}
diff --git a/sys/dev/aic7xxx/aicasm.h b/sys/dev/aic7xxx/aicasm.h
deleted file mode 100644
index 185d807f6788d..0000000000000
--- a/sys/dev/aic7xxx/aicasm.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Assembler for the sequencer program downloaded to Aic7xxx SCSI host adapters
- *
- * Copyright (c) 1997 Justin T. Gibbs.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- */
-
-#include <sys/queue.h>
-
-#ifndef TRUE
-#define TRUE 1
-#endif
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-typedef struct path_entry {
- char *directory;
- int quoted_includes_only;
- SLIST_ENTRY(path_entry) links;
-} *path_entry_t;
-
-typedef enum {
- QUOTED_INCLUDE,
- BRACKETED_INCLUDE,
- SOURCE_FILE
-} include_type;
-
-SLIST_HEAD(path_list, path_entry);
-
-extern struct path_list search_path;
-extern struct symlist patch_options;
-extern int includes_search_curdir; /* False if we've seen -I- */
-extern char *appname;
-extern int yylineno;
-extern char *yyfilename;
-
-void stop __P((const char *errstring, int err_code));
-void include_file __P((char *file_name, include_type type));
-struct instruction *seq_alloc __P((void));
-struct patch *patch_alloc __P((void));
diff --git a/sys/dev/aic7xxx/aicasm_gram.y b/sys/dev/aic7xxx/aicasm_gram.y
deleted file mode 100644
index 0c75edca3b3ee..0000000000000
--- a/sys/dev/aic7xxx/aicasm_gram.y
+++ /dev/null
@@ -1,1304 +0,0 @@
-%{
-/*
- * Parser for the Aic7xxx SCSI Host adapter sequencer assembler.
- *
- * Copyright (c) 1997 Justin T. Gibbs.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-
-#include <sys/types.h>
-#include <sys/queue.h>
-
-#include "aic7xxx_asm.h"
-#include "symbol.h"
-#include "sequencer.h"
-
-int yylineno;
-char *yyfilename;
-static symbol_t *cur_symbol;
-static symtype cur_symtype;
-static symbol_t *accumulator;
-static symbol_ref_t allones;
-static symbol_ref_t allzeros;
-static symbol_ref_t none;
-static symbol_ref_t sindex;
-static int instruction_ptr;
-static int sram_or_scb_offset;
-static patch_t *cur_patch;
-
-static void process_bitmask __P((int mask_type, symbol_t *sym, int mask));
-static void initialize_symbol __P((symbol_t *symbol));
-static void process_register __P((symbol_t **p_symbol));
-static void format_1_instr __P((int opcode, symbol_ref_t *dest,
- expression_t *immed, symbol_ref_t *src,
- int ret));
-static void format_2_instr __P((int opcode, symbol_ref_t *dest,
- expression_t *places, symbol_ref_t *src,
- int ret));
-static void format_3_instr __P((int opcode, symbol_ref_t *src,
- expression_t *immed, symbol_ref_t *address));
-static void test_readable_symbol __P((symbol_t *symbol));
-static void test_writable_symbol __P((symbol_t *symbol));
-static void type_check __P((symbol_t *symbol, expression_t *expression,
- int and_op));
-static void make_expression __P((expression_t *immed, int value));
-static void add_conditional __P((symbol_t *symbol));
-
-#define YYDEBUG 1
-#define SRAM_SYMNAME "SRAM_BASE"
-#define SCB_SYMNAME "SCB_BASE"
-%}
-
-%union {
- int value;
- char *str;
- symbol_t *sym;
- symbol_ref_t sym_ref;
- expression_t expression;
-}
-
-%token T_REGISTER
-
-%token <value> T_CONST
-
-%token T_SCB
-
-%token T_SRAM
-
-%token T_ALIAS
-
-%token T_SIZE
-
-%token <value> T_ADDRESS
-
-%token T_ACCESS_MODE
-
-%token <value> T_MODE
-
-%token T_BIT
-
-%token T_MASK
-
-%token <value> T_NUMBER
-
-%token <str> T_PATH
-
-%token T_EOF T_INCLUDE
-
-%token <value> T_SHR T_SHL T_ROR T_ROL
-
-%token <value> T_MVI T_MOV T_CLR
-
-%token <value> T_JMP T_JC T_JNC T_JE T_JNE T_JNZ T_JZ T_CALL
-
-%token <value> T_ADD T_ADC
-
-%token <value> T_INC T_DEC
-
-%token <value> T_STC T_CLC
-
-%token <value> T_CMP T_XOR
-
-%token <value> T_TEST T_AND
-
-%token <value> T_OR
-
-%token T_RET
-
-%token T_NOP
-
-%token T_ACCUM T_ALLONES T_ALLZEROS T_NONE T_SINDEX
-
-%token T_A
-
-%token <sym> T_SYMBOL
-
-%token T_NL
-
-%token T_IF T_ELSE T_ENDIF
-
-%type <sym_ref> reg_symbol address destination source opt_source
-
-%type <expression> expression immediate immediate_or_a
-
-%type <value> ret f1_opcode f2_opcode jmp_jc_jnc_call jz_jnz je_jne
-
-%left '|'
-%left '&'
-%left '+' '-'
-%right '~'
-%nonassoc UMINUS
-%%
-
-program:
- include
-| program include
-| register
-| program register
-| constant
-| program constant
-| scratch_ram
-| program scratch_ram
-| scb
-| program scb
-| label
-| program label
-| conditional
-| program conditional
-| code
-| program code
-;
-
-include:
- T_INCLUDE '<' T_PATH '>'
- { include_file($3, BRACKETED_INCLUDE); }
-| T_INCLUDE '"' T_PATH '"'
- { include_file($3, QUOTED_INCLUDE); }
-;
-
-register:
- T_REGISTER { cur_symtype = REGISTER; } reg_definition
-;
-
-reg_definition:
- T_SYMBOL '{'
- {
- if ($1->type != UNINITIALIZED) {
- stop("Register multiply defined", EX_DATAERR);
- /* NOTREACHED */
- }
- cur_symbol = $1;
- cur_symbol->type = cur_symtype;
- initialize_symbol(cur_symbol);
- }
- reg_attribute_list
- '}'
- {
- /*
- * Default to allowing everything in for registers
- * with no bit or mask definitions.
- */
- if (cur_symbol->info.rinfo->valid_bitmask == 0)
- cur_symbol->info.rinfo->valid_bitmask = 0xFF;
-
- if (cur_symbol->info.rinfo->size == 0)
- cur_symbol->info.rinfo->size = 1;
-
- /*
- * This might be useful for registers too.
- */
- if (cur_symbol->type != REGISTER) {
- if (cur_symbol->info.rinfo->address == 0)
- cur_symbol->info.rinfo->address =
- sram_or_scb_offset;
- sram_or_scb_offset +=
- cur_symbol->info.rinfo->size;
- }
- cur_symbol = NULL;
- }
-;
-
-reg_attribute_list:
- reg_attribute
-| reg_attribute_list reg_attribute
-;
-
-reg_attribute:
- reg_address
-| size
-| access_mode
-| bit_defn
-| mask_defn
-| alias
-| accumulator
-| allones
-| allzeros
-| none
-| sindex
-;
-
-reg_address:
- T_ADDRESS T_NUMBER
- {
- cur_symbol->info.rinfo->address = $2;
- }
-;
-
-size:
- T_SIZE T_NUMBER
- {
- cur_symbol->info.rinfo->size = $2;
- }
-;
-
-access_mode:
- T_ACCESS_MODE T_MODE
- {
- cur_symbol->info.rinfo->mode = $2;
- }
-;
-
-bit_defn:
- T_BIT T_SYMBOL T_NUMBER
- {
- process_bitmask(BIT, $2, $3);
- }
-;
-
-mask_defn:
- T_MASK T_SYMBOL expression
- {
- process_bitmask(MASK, $2, $3.value);
- }
-;
-
-alias:
- T_ALIAS T_SYMBOL
- {
- if ($2->type != UNINITIALIZED) {
- stop("Re-definition of register alias",
- EX_DATAERR);
- /* NOTREACHED */
- }
- $2->type = ALIAS;
- initialize_symbol($2);
- $2->info.ainfo->parent = cur_symbol;
- }
-;
-
-accumulator:
- T_ACCUM
- {
- if (accumulator != NULL) {
- stop("Only one accumulator definition allowed",
- EX_DATAERR);
- /* NOTREACHED */
- }
- accumulator = cur_symbol;
- }
-;
-
-allones:
- T_ALLONES
- {
- if (allones.symbol != NULL) {
- stop("Only one definition of allones allowed",
- EX_DATAERR);
- /* NOTREACHED */
- }
- allones.symbol = cur_symbol;
- }
-;
-
-allzeros:
- T_ALLZEROS
- {
- if (allzeros.symbol != NULL) {
- stop("Only one definition of allzeros allowed",
- EX_DATAERR);
- /* NOTREACHED */
- }
- allzeros.symbol = cur_symbol;
- }
-;
-
-none:
- T_NONE
- {
- if (none.symbol != NULL) {
- stop("Only one definition of none allowed",
- EX_DATAERR);
- /* NOTREACHED */
- }
- none.symbol = cur_symbol;
- }
-;
-
-sindex:
- T_SINDEX
- {
- if (sindex.symbol != NULL) {
- stop("Only one definition of sindex allowed",
- EX_DATAERR);
- /* NOTREACHED */
- }
- sindex.symbol = cur_symbol;
- }
-;
-
-expression:
- expression '|' expression
- {
- $$.value = $1.value | $3.value;
- symlist_merge(&$$.referenced_syms,
- &$1.referenced_syms,
- &$3.referenced_syms);
- }
-| expression '&' expression
- {
- $$.value = $1.value & $3.value;
- symlist_merge(&$$.referenced_syms,
- &$1.referenced_syms,
- &$3.referenced_syms);
- }
-| expression '+' expression
- {
- $$.value = $1.value + $3.value;
- symlist_merge(&$$.referenced_syms,
- &$1.referenced_syms,
- &$3.referenced_syms);
- }
-| expression '-' expression
- {
- $$.value = $1.value - $3.value;
- symlist_merge(&($$.referenced_syms),
- &($1.referenced_syms),
- &($3.referenced_syms));
- }
-| '(' expression ')'
- {
- $$ = $2;
- }
-| '~' expression
- {
- $$ = $2;
- $$.value = (~$$.value) & 0xFF;
- }
-| '-' expression %prec UMINUS
- {
- $$ = $2;
- $$.value = -$$.value;
- }
-| T_NUMBER
- {
- $$.value = $1;
- SLIST_INIT(&$$.referenced_syms);
- }
-| T_SYMBOL
- {
- symbol_t *symbol;
-
- symbol = $1;
- switch (symbol->type) {
- case ALIAS:
- symbol = $1->info.ainfo->parent;
- case REGISTER:
- case SCBLOC:
- case SRAMLOC:
- $$.value = symbol->info.rinfo->address;
- break;
- case MASK:
- case BIT:
- $$.value = symbol->info.minfo->mask;
- break;
- case CONST:
- $$.value = symbol->info.cinfo->value;
- break;
- case UNINITIALIZED:
- default:
- {
- char buf[255];
-
- snprintf(buf, sizeof(buf),
- "Undefined symbol %s referenced",
- symbol->name);
- stop(buf, EX_DATAERR);
- /* NOTREACHED */
- break;
- }
- }
- SLIST_INIT(&$$.referenced_syms);
- symlist_add(&$$.referenced_syms, symbol, SYMLIST_INSERT_HEAD);
- }
-;
-
-constant:
- T_CONST T_SYMBOL T_NUMBER
- {
- if ($2->type != UNINITIALIZED) {
- stop("Re-definition of constant variable",
- EX_DATAERR);
- /* NOTREACHED */
- }
- $2->type = CONST;
- initialize_symbol($2);
- $2->info.cinfo->value = $3;
- $2->info.cinfo->define = $1;
- }
-;
-
-scratch_ram:
- T_SRAM '{'
- {
- cur_symbol = symtable_get(SRAM_SYMNAME);
- cur_symtype = SRAMLOC;
- if (cur_symbol->type != UNINITIALIZED) {
- stop("Only one SRAM definition allowed",
- EX_DATAERR);
- /* NOTREACHED */
- }
- cur_symbol->type = SRAMLOC;
- initialize_symbol(cur_symbol);
- }
- reg_address
- {
- sram_or_scb_offset = cur_symbol->info.rinfo->address;
- }
- scb_or_sram_reg_list
- '}'
- {
- cur_symbol = NULL;
- }
-;
-
-scb:
- T_SCB '{'
- {
- cur_symbol = symtable_get(SCB_SYMNAME);
- cur_symtype = SCBLOC;
- if (cur_symbol->type != UNINITIALIZED) {
- stop("Only one SRAM definition allowed",
- EX_SOFTWARE);
- /* NOTREACHED */
- }
- cur_symbol->type = SCBLOC;
- initialize_symbol(cur_symbol);
- }
- reg_address
- {
- sram_or_scb_offset = cur_symbol->info.rinfo->address;
- }
- scb_or_sram_reg_list
- '}'
- {
- cur_symbol = NULL;
- }
-;
-
-scb_or_sram_reg_list:
- reg_definition
-| scb_or_sram_reg_list reg_definition
-;
-
-reg_symbol:
- T_SYMBOL
- {
- process_register(&$1);
- $$.symbol = $1;
- $$.offset = 0;
- }
-| T_SYMBOL '[' T_NUMBER ']'
- {
- process_register(&$1);
- if (($3 + 1) > $1->info.rinfo->size) {
- stop("Accessing offset beyond range of register",
- EX_DATAERR);
- /* NOTREACHED */
- }
- $$.symbol = $1;
- $$.offset = $3;
- }
-| T_A
- {
- if (accumulator == NULL) {
- stop("No accumulator has been defined", EX_DATAERR);
- /* NOTREACHED */
- }
- $$.symbol = accumulator;
- $$.offset = 0;
- }
-;
-
-destination:
- reg_symbol
- {
- test_writable_symbol($1.symbol);
- $$ = $1;
- }
-;
-
-immediate:
- expression
- { $$ = $1; }
-;
-
-immediate_or_a:
- expression
- {
- $$ = $1;
- }
-| T_A
- {
- SLIST_INIT(&$$.referenced_syms);
- $$.value = 0;
- }
-;
-
-source:
- reg_symbol
- {
- test_readable_symbol($1.symbol);
- $$ = $1;
- }
-;
-
-opt_source:
- {
- $$.symbol = NULL;
- $$.offset = 0;
- }
-| ',' source
- { $$ = $2; }
-;
-
-ret:
- { $$ = 0; }
-| T_RET
- { $$ = 1; }
-;
-
-label:
- T_SYMBOL ':'
- {
- if ($1->type != UNINITIALIZED) {
- stop("Program label multiply defined", EX_DATAERR);
- /* NOTREACHED */
- }
- $1->type = LABEL;
- initialize_symbol($1);
- $1->info.linfo->address = instruction_ptr;
- }
-;
-
-address:
- T_SYMBOL
- {
- $$.symbol = $1;
- $$.offset = 0;
- }
-| T_SYMBOL '+' T_NUMBER
- {
- $$.symbol = $1;
- $$.offset = $3;
- }
-| T_SYMBOL '-' T_NUMBER
- {
- $$.symbol = $1;
- $$.offset = -$3;
- }
-| '.'
- {
- $$.symbol = NULL;
- $$.offset = 0;
- }
-| '.' '+' T_NUMBER
- {
- $$.symbol = NULL;
- $$.offset = $3;
- }
-| '.' '-' T_NUMBER
- {
- $$.symbol = NULL;
- $$.offset = -$3;
- }
-;
-
-conditional:
- T_IF
- {
- if (cur_patch != NULL) {
- stop("Nested .if directive", EX_DATAERR);
- /* NOTREACHED */
- }
- cur_patch = patch_alloc();
- cur_patch->begin = instruction_ptr;
- }
- option_list
-;
-
-conditional:
- T_ELSE
- {
- patch_t *next_patch;
-
- if (cur_patch == NULL) {
- stop(".else outsize of .if", EX_DATAERR);
- /* NOTREACHED */
- }
- cur_patch->end = instruction_ptr;
- next_patch = patch_alloc();
- next_patch->options = cur_patch->options;
- next_patch->negative = cur_patch->negative ? FALSE : TRUE;
- cur_patch = next_patch;
- cur_patch->begin = instruction_ptr;
- }
-;
-
-conditional:
- T_ENDIF
- {
- if (cur_patch == NULL) {
- stop(".endif outsize of .if", EX_DATAERR);
- /* NOTREACHED */
- }
- cur_patch->end = instruction_ptr;
- cur_patch = NULL;
- }
-;
-
-option_list:
- '(' option_symbol_list ')'
-| '!' option_list
- {
- cur_patch->negative = cur_patch->negative ? FALSE : TRUE;
- }
-;
-
-option_symbol_list:
- T_SYMBOL
- {
- add_conditional($1);
- }
-| option_list '|' T_SYMBOL
- {
- add_conditional($3);
- }
-;
-
-f1_opcode:
- T_AND { $$ = AIC_OP_AND; }
-| T_XOR { $$ = AIC_OP_XOR; }
-| T_ADD { $$ = AIC_OP_ADD; }
-| T_ADC { $$ = AIC_OP_ADC; }
-;
-
-code:
- f1_opcode destination ',' immediate_or_a opt_source ret ';'
- {
- format_1_instr($1, &$2, &$4, &$5, $6);
- }
-;
-
-code:
- T_OR reg_symbol ',' immediate_or_a opt_source ret ';'
- {
- format_1_instr(AIC_OP_OR, &$2, &$4, &$5, $6);
- }
-;
-
-code:
- T_INC destination opt_source ret ';'
- {
- expression_t immed;
-
- make_expression(&immed, 1);
- format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4);
- }
-;
-
-code:
- T_DEC destination opt_source ret ';'
- {
- expression_t immed;
-
- make_expression(&immed, -1);
- format_1_instr(AIC_OP_ADD, &$2, &immed, &$3, $4);
- }
-;
-
-code:
- T_CLC ret ';'
- {
- expression_t immed;
-
- make_expression(&immed, -1);
- format_1_instr(AIC_OP_ADD, &none, &immed, &allzeros, $2);
- }
-| T_CLC T_MVI destination ',' immediate_or_a ret ';'
- {
- format_1_instr(AIC_OP_ADD, &$3, &$5, &allzeros, $6);
- }
-;
-
-code:
- T_STC ret ';'
- {
- expression_t immed;
-
- make_expression(&immed, 1);
- format_1_instr(AIC_OP_ADD, &none, &immed, &allones, $2);
- }
-| T_STC destination ret ';'
- {
- expression_t immed;
-
- make_expression(&immed, 1);
- format_1_instr(AIC_OP_ADD, &$2, &immed, &allones, $3);
- }
-;
-
-code:
- T_MOV destination ',' source ret ';'
- {
- expression_t immed;
-
- make_expression(&immed, 0xff);
- format_1_instr(AIC_OP_AND, &$2, &immed, &$4, $5);
- }
-;
-
-code:
- T_MVI destination ',' immediate_or_a ret ';'
- {
- format_1_instr(AIC_OP_OR, &$2, &$4, &allzeros, $5);
- }
-;
-
-code:
- T_CLR destination ret ';'
- {
- expression_t immed;
-
- make_expression(&immed, 0xff);
- format_1_instr(AIC_OP_AND, &$2, &immed, &allzeros, $3);
- }
-;
-
-code:
- T_NOP ';'
- {
- expression_t immed;
-
- make_expression(&immed, 0xff);
- format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, FALSE);
- }
-;
-
-code:
- T_RET ';'
- {
- expression_t immed;
-
- make_expression(&immed, 0xff);
- format_1_instr(AIC_OP_AND, &none, &immed, &allzeros, TRUE);
- }
-;
-
- /*
- * This grammer differs from the one in the aic7xxx
- * reference manual since the grammer listed there is
- * ambiguous and causes a shift/reduce conflict.
- * It also seems more logical as the "immediate"
- * argument is listed as the second arg like the
- * other formats.
- */
-
-f2_opcode:
- T_SHL { $$ = AIC_OP_SHL; }
-| T_SHR { $$ = AIC_OP_SHR; }
-| T_ROL { $$ = AIC_OP_ROL; }
-| T_ROR { $$ = AIC_OP_ROR; }
-;
-
-code:
- f2_opcode destination ',' expression opt_source ret ';'
- {
- format_2_instr($1, &$2, &$4, &$5, $6);
- }
-;
-
-jmp_jc_jnc_call:
- T_JMP { $$ = AIC_OP_JMP; }
-| T_JC { $$ = AIC_OP_JC; }
-| T_JNC { $$ = AIC_OP_JNC; }
-| T_CALL { $$ = AIC_OP_CALL; }
-;
-
-jz_jnz:
- T_JZ { $$ = AIC_OP_JZ; }
-| T_JNZ { $$ = AIC_OP_JNZ; }
-;
-
-je_jne:
- T_JE { $$ = AIC_OP_JE; }
-| T_JNE { $$ = AIC_OP_JNE; }
-;
-
-code:
- jmp_jc_jnc_call address ';'
- {
- expression_t immed;
-
- make_expression(&immed, 0);
- format_3_instr($1, &sindex, &immed, &$2);
- }
-;
-
-code:
- T_OR reg_symbol ',' immediate jmp_jc_jnc_call address ';'
- {
- format_3_instr($5, &$2, &$4, &$6);
- }
-;
-
-code:
- T_TEST source ',' immediate_or_a jz_jnz address ';'
- {
- format_3_instr($5, &$2, &$4, &$6);
- }
-;
-
-code:
- T_CMP source ',' immediate_or_a je_jne address ';'
- {
- format_3_instr($5, &$2, &$4, &$6);
- }
-;
-
-code:
- T_MOV source jmp_jc_jnc_call address ';'
- {
- expression_t immed;
-
- make_expression(&immed, 0);
- format_3_instr($3, &$2, &immed, &$4);
- }
-;
-
-code:
- T_MVI immediate jmp_jc_jnc_call address ';'
- {
- format_3_instr($3, &allzeros, &$2, &$4);
- }
-;
-
-%%
-
-static void
-process_bitmask(mask_type, sym, mask)
- int mask_type;
- symbol_t *sym;
- int mask;
-{
- /*
- * Add the current register to its
- * symbol list, if it already exists,
- * warn if we are setting it to a
- * different value, or in the bit to
- * the "allowed bits" of this register.
- */
- if (sym->type == UNINITIALIZED) {
- sym->type = mask_type;
- initialize_symbol(sym);
- if (mask_type == BIT) {
- if (mask == 0) {
- stop("Bitmask with no bits set", EX_DATAERR);
- /* NOTREACHED */
- }
- if ((mask & ~(0x01 << (ffs(mask) - 1))) != 0) {
- stop("Bitmask with more than one bit set",
- EX_DATAERR);
- /* NOTREACHED */
- }
- }
- sym->info.minfo->mask = mask;
- } else if (sym->type != mask_type) {
- stop("Bit definition mirrors a definition of the same "
- " name, but a different type", EX_DATAERR);
- /* NOTREACHED */
- } else if (mask != sym->info.minfo->mask) {
- stop("Bitmask redefined with a conflicting value", EX_DATAERR);
- /* NOTREACHED */
- }
- /* Fail if this symbol is already listed */
- if (symlist_search(&(sym->info.minfo->symrefs),
- cur_symbol->name) != NULL) {
- stop("Bitmask defined multiple times for register", EX_DATAERR);
- /* NOTREACHED */
- }
- symlist_add(&(sym->info.minfo->symrefs), cur_symbol,
- SYMLIST_INSERT_HEAD);
- cur_symbol->info.rinfo->valid_bitmask |= mask;
- cur_symbol->info.rinfo->typecheck_masks = TRUE;
-}
-
-static void
-initialize_symbol(symbol)
- symbol_t *symbol;
-{
- switch (symbol->type) {
- case UNINITIALIZED:
- stop("Call to initialize_symbol with type field unset",
- EX_SOFTWARE);
- /* NOTREACHED */
- break;
- case REGISTER:
- case SRAMLOC:
- case SCBLOC:
- symbol->info.rinfo =
- (struct reg_info *)malloc(sizeof(struct reg_info));
- if (symbol->info.rinfo == NULL) {
- stop("Can't create register info", EX_SOFTWARE);
- /* NOTREACHED */
- }
- memset(symbol->info.rinfo, 0,
- sizeof(struct reg_info));
- break;
- case ALIAS:
- symbol->info.ainfo =
- (struct alias_info *)malloc(sizeof(struct alias_info));
- if (symbol->info.ainfo == NULL) {
- stop("Can't create alias info", EX_SOFTWARE);
- /* NOTREACHED */
- }
- memset(symbol->info.ainfo, 0,
- sizeof(struct alias_info));
- break;
- case MASK:
- case BIT:
- symbol->info.minfo =
- (struct mask_info *)malloc(sizeof(struct mask_info));
- if (symbol->info.minfo == NULL) {
- stop("Can't create bitmask info", EX_SOFTWARE);
- /* NOTREACHED */
- }
- memset(symbol->info.minfo, 0, sizeof(struct mask_info));
- SLIST_INIT(&(symbol->info.minfo->symrefs));
- break;
- case CONST:
- symbol->info.cinfo =
- (struct const_info *)malloc(sizeof(struct const_info));
- if (symbol->info.cinfo == NULL) {
- stop("Can't create alias info", EX_SOFTWARE);
- /* NOTREACHED */
- }
- memset(symbol->info.cinfo, 0,
- sizeof(struct const_info));
- break;
- case LABEL:
- symbol->info.linfo =
- (struct label_info *)malloc(sizeof(struct label_info));
- if (symbol->info.linfo == NULL) {
- stop("Can't create label info", EX_SOFTWARE);
- /* NOTREACHED */
- }
- memset(symbol->info.linfo, 0,
- sizeof(struct label_info));
- break;
- case CONDITIONAL:
- symbol->info.condinfo =
- (struct cond_info *)malloc(sizeof(struct cond_info));
- if (symbol->info.condinfo == NULL) {
- stop("Can't create conditional info", EX_SOFTWARE);
- /* NOTREACHED */
- }
- memset(symbol->info.condinfo, 0,
- sizeof(struct cond_info));
- break;
- default:
- stop("Call to initialize_symbol with invalid symbol type",
- EX_SOFTWARE);
- /* NOTREACHED */
- break;
- }
-}
-
-static void
-process_register(p_symbol)
- symbol_t **p_symbol;
-{
- char buf[255];
- symbol_t *symbol = *p_symbol;
-
- if (symbol->type == UNINITIALIZED) {
- snprintf(buf, sizeof(buf), "Undefined register %s",
- symbol->name);
- stop(buf, EX_DATAERR);
- /* NOTREACHED */
- } else if (symbol->type == ALIAS) {
- *p_symbol = symbol->info.ainfo->parent;
- } else if ((symbol->type != REGISTER)
- && (symbol->type != SCBLOC)
- && (symbol->type != SRAMLOC)) {
- snprintf(buf, sizeof(buf),
- "Specified symbol %s is not a register",
- symbol->name);
- stop(buf, EX_DATAERR);
- }
-}
-
-static void
-format_1_instr(opcode, dest, immed, src, ret)
- int opcode;
- symbol_ref_t *dest;
- expression_t *immed;
- symbol_ref_t *src;
- int ret;
-{
- struct instruction *instr;
- struct ins_format1 *f1_instr;
-
- if (src->symbol == NULL)
- src = dest;
-
- /* Test register permissions */
- test_writable_symbol(dest->symbol);
- test_readable_symbol(src->symbol);
-
- /* Ensure that immediate makes sense for this destination */
- type_check(dest->symbol, immed, opcode);
-
- /* Allocate sequencer space for the instruction and fill it out */
- instr = seq_alloc();
- f1_instr = &instr->format.format1;
- f1_instr->opcode_ret = (opcode << 1) | (ret ? RETURN_BIT : 0);
- f1_instr->destination = dest->symbol->info.rinfo->address
- + dest->offset;
- f1_instr->source = src->symbol->info.rinfo->address
- + src->offset;
- f1_instr->immediate = immed->value;
- symlist_free(&immed->referenced_syms);
- instruction_ptr++;
-}
-
-static void
-format_2_instr(opcode, dest, places, src, ret)
- int opcode;
- symbol_ref_t *dest;
- expression_t *places;
- symbol_ref_t *src;
- int ret;
-{
- struct instruction *instr;
- struct ins_format2 *f2_instr;
- u_int8_t shift_control;
-
- if (src->symbol == NULL)
- src = dest;
-
- /* Test register permissions */
- test_writable_symbol(dest->symbol);
- test_readable_symbol(src->symbol);
-
- /* Allocate sequencer space for the instruction and fill it out */
- instr = seq_alloc();
- f2_instr = &instr->format.format2;
- f2_instr->opcode_ret = (AIC_OP_ROL << 1) | (ret ? RETURN_BIT : 0);
- f2_instr->destination = dest->symbol->info.rinfo->address
- + dest->offset;
- f2_instr->source = src->symbol->info.rinfo->address
- + src->offset;
- if (places->value > 8 || places->value <= 0) {
- stop("illegal shift value", EX_DATAERR);
- /* NOTREACHED */
- }
- switch (opcode) {
- case AIC_OP_SHL:
- if (places->value == 8)
- shift_control = 0xf0;
- else
- shift_control = (places->value << 4) | places->value;
- break;
- case AIC_OP_SHR:
- if (places->value == 8) {
- shift_control = 0xf8;
- } else {
- shift_control = (places->value << 4)
- | (8 - places->value)
- | 0x08;
- }
- break;
- case AIC_OP_ROL:
- shift_control = places->value & 0x7;
- break;
- case AIC_OP_ROR:
- shift_control = (8 - places->value) | 0x08;
- break;
- default:
- shift_control = 0; /* Quiet Compiler */
- stop("Invalid shift operation specified", EX_SOFTWARE);
- /* NOTREACHED */
- break;
- };
- f2_instr->shift_control = shift_control;
- symlist_free(&places->referenced_syms);
- instruction_ptr++;
-}
-
-static void
-format_3_instr(opcode, src, immed, address)
- int opcode;
- symbol_ref_t *src;
- expression_t *immed;
- symbol_ref_t *address;
-{
- struct instruction *instr;
- struct ins_format3 *f3_instr;
- int addr;
-
- /* Test register permissions */
- test_readable_symbol(src->symbol);
-
- /* Ensure that immediate makes sense for this source */
- type_check(src->symbol, immed, opcode);
-
- /* Allocate sequencer space for the instruction and fill it out */
- instr = seq_alloc();
- f3_instr = &instr->format.format3;
- if (address->symbol == NULL) {
- /* 'dot' referrence. Use the current instruction pointer */
- addr = instruction_ptr + address->offset;
- } else if (address->symbol->type == UNINITIALIZED) {
- /* forward reference */
- addr = address->offset;
- instr->patch_label = address->symbol;
- } else
- addr = address->symbol->info.linfo->address + address->offset;
- f3_instr->opcode_addr = (opcode << 1)
- | ((addr >> 8) & 0x01);
- f3_instr->address = addr & 0xff;
- f3_instr->source = src->symbol->info.rinfo->address
- + src->offset;
- f3_instr->immediate = immed->value;
- symlist_free(&immed->referenced_syms);
- instruction_ptr++;
-}
-
-static void
-test_readable_symbol(symbol)
- symbol_t *symbol;
-{
- if (symbol->info.rinfo->mode == WO) {
- stop("Write Only register specified as source",
- EX_DATAERR);
- /* NOTREACHED */
- }
-}
-
-static void
-test_writable_symbol(symbol)
- symbol_t *symbol;
-{
- if (symbol->info.rinfo->mode == RO) {
- stop("Read Only register specified as destination",
- EX_DATAERR);
- /* NOTREACHED */
- }
-}
-
-static void
-type_check(symbol, expression, opcode)
- symbol_t *symbol;
- expression_t *expression;
- int opcode;
-{
- symbol_node_t *node;
- int and_op;
- char buf[255];
-
- and_op = FALSE;
- if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ)
- and_op = TRUE;
- /*
- * Make sure that we aren't attempting to write something
- * that hasn't been defined. If this is an and operation,
- * this is a mask, so "undefined" bits are okay.
- */
- if (and_op == FALSE
- && (expression->value & ~symbol->info.rinfo->valid_bitmask) != 0) {
- snprintf(buf, sizeof(buf),
- "Invalid bit(s) 0x%x in immediate written to %s",
- expression->value & ~symbol->info.rinfo->valid_bitmask,
- symbol->name);
- stop(buf, EX_DATAERR);
- /* NOTREACHED */
- }
-
- /*
- * Now make sure that all of the symbols referenced by the
- * expression are defined for this register.
- */
- if(symbol->info.rinfo->typecheck_masks != FALSE) {
- for(node = expression->referenced_syms.slh_first;
- node != NULL;
- node = node->links.sle_next) {
- if ((node->symbol->type == MASK
- || node->symbol->type == BIT)
- && symlist_search(&node->symbol->info.minfo->symrefs,
- symbol->name) == NULL) {
- snprintf(buf, sizeof(buf),
- "Invalid bit or mask %s "
- "for register %s",
- node->symbol->name, symbol->name);
- stop(buf, EX_DATAERR);
- /* NOTREACHED */
- }
- }
- }
-}
-
-static void
-make_expression(immed, value)
- expression_t *immed;
- int value;
-{
- SLIST_INIT(&immed->referenced_syms);
- immed->value = value & 0xff;
-}
-
-static void
-add_conditional(symbol)
- symbol_t *symbol;
-{
- static int numoptions = 1;
-
- if (symbol->type == UNINITIALIZED) {
- symbol->type = CONDITIONAL;
- initialize_symbol(symbol);
- symbol->info.condinfo->value = 0x01 << numoptions++;
- symlist_add(&patch_options, symbol, SYMLIST_INSERT_HEAD);
- } else if (symbol->type != CONDITIONAL) {
- stop("Conditional symbol mirrors other symbol",
- EX_DATAERR);
- /* NOTREACHED */
- }
- cur_patch->options |= symbol->info.condinfo->value;
-}
-
-void
-yyerror(string)
- const char *string;
-{
- stop(string, EX_DATAERR);
-}
diff --git a/sys/dev/aic7xxx/aicasm_scan.l b/sys/dev/aic7xxx/aicasm_scan.l
deleted file mode 100644
index 0caf46a8d7db2..0000000000000
--- a/sys/dev/aic7xxx/aicasm_scan.l
+++ /dev/null
@@ -1,243 +0,0 @@
-%{
-/*
- * Lexical Analyzer for the Aic7xxx SCSI Host adapter sequencer assembler.
- *
- * Copyright (c) 1997 Justin T. Gibbs.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id: scan.l,v 1.1 1997/03/16 07:08:17 gibbs Exp $
- */
-
-#include <limits.h>
-#include <stdio.h>
-#include <string.h>
-#include <sysexits.h>
-#include <sys/queue.h>
-#include <sys/types.h>
-
-#include "aic7xxx_asm.h"
-#include "symbol.h"
-#include "y.tab.h"
-%}
-
-PATH [-/A-Za-z0-9_.]*[./][-/A-Za-z0-9_.]*
-WORD [A-Za-z_][-A-Za-z_0-9]*
-SPACE [ \t]+
-
-%x COMMENT
-
-%%
-\n { ++yylineno; }
-"/*" { BEGIN COMMENT; /* Enter comment eating state */ }
-<COMMENT>"/*" { fprintf(stderr, "Warning! Comment within comment."); }
-<COMMENT>\n { ++yylineno; }
-<COMMENT>[^*/\n]* ;
-<COMMENT>"*"+[^*/\n]* ;
-<COMMENT>"/"+[^*/\n]* ;
-<COMMENT>"*"+"/" { BEGIN INITIAL; }
-
-{SPACE} ;
-
- /* Register/SCB/SRAM definition keywords */
-register { return T_REGISTER; }
-const { yylval.value = FALSE; return T_CONST; }
-address { return T_ADDRESS; }
-access_mode { return T_ACCESS_MODE; }
-RW|RO|WO {
- if (strcmp(yytext, "RW") == 0)
- yylval.value = RW;
- else if (strcmp(yytext, "RO") == 0)
- yylval.value = RO;
- else
- yylval.value = WO;
- return T_MODE;
- }
-bit { return T_BIT; }
-mask { return T_MASK; }
-alias { return T_ALIAS; }
-size { return T_SIZE; }
-scb { return T_SCB; }
-scratch_ram { return T_SRAM; }
-accumulator { return T_ACCUM; }
-allones { return T_ALLONES; }
-allzeros { return T_ALLZEROS; }
-none { return T_NONE; }
-sindex { return T_SINDEX; }
-A { return T_A; }
-
- /* Opcodes */
-shl { return T_SHL; }
-shr { return T_SHR; }
-ror { return T_ROR; }
-rol { return T_ROL; }
-mvi { return T_MVI; }
-mov { return T_MOV; }
-clr { return T_CLR; }
-jmp { return T_JMP; }
-jc { return T_JC; }
-jnc { return T_JNC; }
-je { return T_JE; }
-jne { return T_JNE; }
-jz { return T_JZ; }
-jnz { return T_JNZ; }
-call { return T_CALL; }
-add { return T_ADD; }
-adc { return T_ADC; }
-inc { return T_INC; }
-dec { return T_DEC; }
-stc { return T_STC; }
-clc { return T_CLC; }
-cmp { return T_CMP; }
-xor { return T_XOR; }
-test { return T_TEST;}
-and { return T_AND; }
-or { return T_OR; }
-ret { return T_RET; }
-nop { return T_NOP; }
-.if { return T_IF; }
-.else { return T_ELSE; }
-.endif { return T_ENDIF; }
-
- /* Allowed Symbols */
-[-+,:()~|&."{};<>[\]!] { return yytext[0]; }
-
- /* Number processing */
-0[0-7]* {
- yylval.value = strtol(yytext, NULL, 8);
- return T_NUMBER;
- }
-
-0[xX][0-9a-fA-F]+ {
- yylval.value = strtoul(yytext + 2, NULL, 16);
- return T_NUMBER;
- }
-
-[1-9][0-9]* {
- yylval.value = strtol(yytext, NULL, 10);
- return T_NUMBER;
- }
-
- /* Include Files */
-#include { return T_INCLUDE; }
-
- /* For parsing C include files with #define foo */
-#define { yylval.value = TRUE; return T_CONST; }
- /* Throw away macros */
-#define[^\n]*[()]+[^\n]* ;
-{PATH} { yylval.str = strdup(yytext); return T_PATH; }
-
-{WORD} { yylval.sym = symtable_get(yytext); return T_SYMBOL; }
-
-. {
- char buf[255];
-
- snprintf(buf, sizeof(buf), "Invalid character "
- "'%c'", yytext[0]);
- stop(buf, EX_DATAERR);
- }
-%%
-
-typedef struct include {
- YY_BUFFER_STATE buffer;
- int lineno;
- char *filename;
- SLIST_ENTRY(include) links;
-}include_t;
-
-SLIST_HEAD(, include) include_stack;
-
-void
-include_file(file_name, type)
- char *file_name;
- include_type type;
-{
- FILE *newfile;
- include_t *include;
-
- newfile = NULL;
- /* Try the current directory first */
- if (includes_search_curdir != 0 || type == SOURCE_FILE)
- newfile = fopen(file_name, "r");
-
- if (newfile == NULL && type != SOURCE_FILE) {
- path_entry_t include_dir;
- for (include_dir = search_path.slh_first;
- include_dir != NULL;
- include_dir = include_dir->links.sle_next) {
- char fullname[PATH_MAX];
-
- if ((include_dir->quoted_includes_only == TRUE)
- && (type != QUOTED_INCLUDE))
- continue;
-
- snprintf(fullname, sizeof(fullname),
- "%s/%s", include_dir->directory, file_name);
-
- if ((newfile = fopen(fullname, "r")) != NULL)
- break;
- }
- }
-
- if (newfile == NULL) {
- perror(file_name);
- stop("Unable to open input file", EX_SOFTWARE);
- /* NOTREACHED */
- }
- include = (include_t *)malloc(sizeof(include_t));
- if (include == NULL) {
- stop("Unable to allocate include stack entry", EX_SOFTWARE);
- /* NOTREACHED */
- }
- include->buffer = YY_CURRENT_BUFFER;
- include->lineno = yylineno;
- include->filename = yyfilename;
- SLIST_INSERT_HEAD(&include_stack, include, links);
- yy_switch_to_buffer(yy_create_buffer(newfile, YY_BUF_SIZE));
- yylineno = 1;
- yyfilename = strdup(file_name);
-}
-
-int
-yywrap()
-{
- include_t *include;
-
- yy_delete_buffer(YY_CURRENT_BUFFER);
- (void)fclose(yyin);
- if (yyfilename != NULL)
- free(yyfilename);
- include = include_stack.slh_first;
- if (include != NULL) {
- yy_switch_to_buffer(include->buffer);
- yylineno = include->lineno;
- yyfilename = include->filename;
- SLIST_REMOVE_HEAD(&include_stack, links);
- free(include);
- return (0);
- }
- return (1);
-}
diff --git a/sys/dev/aic7xxx/aicasm_symbol.c b/sys/dev/aic7xxx/aicasm_symbol.c
deleted file mode 100644
index e2b93efbd2ee1..0000000000000
--- a/sys/dev/aic7xxx/aicasm_symbol.c
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * Aic7xxx SCSI host adapter firmware asssembler symbol table implementation
- *
- * Copyright (c) 1997 Justin T. Gibbs.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- */
-
-
-#include <sys/types.h>
-
-#include <db.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sysexits.h>
-
-#include "symbol.h"
-#include "aic7xxx_asm.h"
-
-static DB *symtable;
-
-symbol_t *
-symbol_create(name)
- char *name;
-{
- symbol_t *new_symbol;
-
- new_symbol = (symbol_t *)malloc(sizeof(symbol_t));
- if (new_symbol == NULL) {
- perror("Unable to create new symbol");
- exit(EX_SOFTWARE);
- }
- memset(new_symbol, 0, sizeof(*new_symbol));
- new_symbol->name = strdup(name);
- new_symbol->type = UNINITIALIZED;
- return (new_symbol);
-}
-
-void
-symbol_delete(symbol)
- symbol_t *symbol;
-{
- if (symtable != NULL) {
- DBT key;
-
- key.data = symbol->name;
- key.size = strlen(symbol->name);
- symtable->del(symtable, &key, /*flags*/0);
- }
- switch(symbol->type) {
- case SCBLOC:
- case SRAMLOC:
- case REGISTER:
- if (symbol->info.rinfo != NULL)
- free(symbol->info.rinfo);
- break;
- case ALIAS:
- if (symbol->info.ainfo != NULL)
- free(symbol->info.ainfo);
- break;
- case MASK:
- case BIT:
- if (symbol->info.minfo != NULL) {
- symlist_free(&symbol->info.minfo->symrefs);
- free(symbol->info.minfo);
- }
- break;
- case CONST:
- if (symbol->info.cinfo != NULL)
- free(symbol->info.cinfo);
- break;
- case LABEL:
- if (symbol->info.linfo != NULL)
- free(symbol->info.linfo);
- break;
- case UNINITIALIZED:
- default:
- break;
- }
- free(symbol->name);
- free(symbol);
-}
-
-void
-symtable_open()
-{
- symtable = dbopen(/*filename*/NULL,
- O_CREAT | O_NONBLOCK | O_RDWR, /*mode*/0, DB_HASH,
- /*openinfo*/NULL);
-
- if (symtable == NULL) {
- perror("Symbol table creation failed");
- exit(EX_SOFTWARE);
- /* NOTREACHED */
- }
-}
-
-void
-symtable_close()
-{
- if (symtable != NULL) {
- DBT key;
- DBT data;
-
- while (symtable->seq(symtable, &key, &data, R_FIRST) == 0) {
- symbol_t *cursym;
-
- cursym = *(symbol_t **)data.data;
- symbol_delete(cursym);
- }
- symtable->close(symtable);
- }
-}
-
-/*
- * The semantics of get is to return an uninitialized symbol entry
- * if a lookup fails.
- */
-symbol_t *
-symtable_get(name)
- char *name;
-{
- DBT key;
- DBT data;
- int retval;
-
- key.data = (void *)name;
- key.size = strlen(name);
-
- if ((retval = symtable->get(symtable, &key, &data, /*flags*/0)) != 0) {
- if (retval == -1) {
- perror("Symbol table get operation failed");
- exit(EX_SOFTWARE);
- /* NOTREACHED */
- } else if (retval == 1) {
- /* Symbol wasn't found, so create a new one */
- symbol_t *new_symbol;
-
- new_symbol = symbol_create(name);
- data.data = &new_symbol;
- data.size = sizeof(new_symbol);
- if (symtable->put(symtable, &key, &data,
- /*flags*/0) !=0) {
- perror("Symtable put failed");
- exit(EX_SOFTWARE);
- }
- return (new_symbol);
- } else {
- perror("Unexpected return value from db get routine");
- exit(EX_SOFTWARE);
- /* NOTREACHED */
- }
- }
- return (*(symbol_t **)data.data);
-}
-
-symbol_node_t *
-symlist_search(symlist, symname)
- symlist_t *symlist;
- char *symname;
-{
- symbol_node_t *curnode;
-
- curnode = symlist->slh_first;
- while(curnode != NULL) {
- if (strcmp(symname, curnode->symbol->name) == 0)
- break;
- curnode = curnode->links.sle_next;
- }
- return (curnode);
-}
-
-void
-symlist_add(symlist, symbol, how)
- symlist_t *symlist;
- symbol_t *symbol;
- int how;
-{
- symbol_node_t *newnode;
-
- newnode = (symbol_node_t *)malloc(sizeof(symbol_node_t));
- if (newnode == NULL) {
- stop("symlist_add: Unable to malloc symbol_node", EX_SOFTWARE);
- /* NOTREACHED */
- }
- newnode->symbol = symbol;
- if (how == SYMLIST_SORT) {
- symbol_node_t *curnode;
- int mask;
-
- mask = FALSE;
- switch(symbol->type) {
- case REGISTER:
- case SCBLOC:
- case SRAMLOC:
- break;
- case BIT:
- case MASK:
- mask = TRUE;
- break;
- default:
- stop("symlist_add: Invalid symbol type for sorting",
- EX_SOFTWARE);
- /* NOTREACHED */
- }
-
- curnode = symlist->slh_first;
- if (curnode == NULL
- || (mask && (curnode->symbol->info.minfo->mask >
- newnode->symbol->info.minfo->mask))
- || (!mask && (curnode->symbol->info.rinfo->address >
- newnode->symbol->info.rinfo->address))) {
- SLIST_INSERT_HEAD(symlist, newnode, links);
- return;
- }
-
- while (1) {
- if (curnode->links.sle_next == NULL) {
- SLIST_INSERT_AFTER(curnode, newnode,
- links);
- break;
- } else {
- symbol_t *cursymbol;
-
- cursymbol = curnode->links.sle_next->symbol;
- if ((mask && (cursymbol->info.minfo->mask >
- symbol->info.minfo->mask))
- || (!mask &&(cursymbol->info.rinfo->address >
- symbol->info.rinfo->address))){
- SLIST_INSERT_AFTER(curnode, newnode,
- links);
- break;
- }
- }
- curnode = curnode->links.sle_next;
- }
- } else {
- SLIST_INSERT_HEAD(symlist, newnode, links);
- }
-}
-
-void
-symlist_free(symlist)
- symlist_t *symlist;
-{
- symbol_node_t *node1, *node2;
-
- node1 = symlist->slh_first;
- while (node1 != NULL) {
- node2 = node1->links.sle_next;
- free(node1);
- node1 = node2;
- }
- SLIST_INIT(symlist);
-}
-
-void
-symlist_merge(symlist_dest, symlist_src1, symlist_src2)
- symlist_t *symlist_dest;
- symlist_t *symlist_src1;
- symlist_t *symlist_src2;
-{
- symbol_node_t *node;
-
- *symlist_dest = *symlist_src1;
- while((node = symlist_src2->slh_first) != NULL) {
- SLIST_REMOVE_HEAD(symlist_src2, links);
- SLIST_INSERT_HEAD(symlist_dest, node, links);
- }
-
- /* These are now empty */
- SLIST_INIT(symlist_src1);
- SLIST_INIT(symlist_src2);
-}
-
-void
-symtable_dump(ofile)
- FILE *ofile;
-{
- /*
- * Sort the registers by address with a simple insertion sort.
- * Put bitmasks next to the first register that defines them.
- * Put constants at the end.
- */
- symlist_t registers;
- symlist_t masks;
- symlist_t constants;
- symlist_t aliases;
-
- SLIST_INIT(&registers);
- SLIST_INIT(&masks);
- SLIST_INIT(&constants);
- SLIST_INIT(&aliases);
-
- if (symtable != NULL) {
- DBT key;
- DBT data;
- int flag = R_FIRST;
-
- while (symtable->seq(symtable, &key, &data, flag) == 0) {
- symbol_t *cursym;
-
- cursym = *(symbol_t **)data.data;
- switch(cursym->type) {
- case REGISTER:
- case SCBLOC:
- case SRAMLOC:
- symlist_add(&registers, cursym, SYMLIST_SORT);
- break;
- case MASK:
- case BIT:
- symlist_add(&masks, cursym, SYMLIST_SORT);
- break;
- case CONST:
- if (cursym->info.cinfo->define == FALSE) {
- symlist_add(&constants, cursym,
- SYMLIST_INSERT_HEAD);
- }
- break;
- case ALIAS:
- symlist_add(&aliases, cursym,
- SYMLIST_INSERT_HEAD);
- default:
- break;
- }
- flag = R_NEXT;
- }
-
- /* Put in the masks and bits */
- while (masks.slh_first != NULL) {
- symbol_node_t *curnode;
- symbol_node_t *regnode;
- char *regname;
-
- curnode = masks.slh_first;
- SLIST_REMOVE_HEAD(&masks, links);
-
- regnode =
- curnode->symbol->info.minfo->symrefs.slh_first;
- regname = regnode->symbol->name;
- regnode = symlist_search(&registers, regname);
- SLIST_INSERT_AFTER(regnode, curnode, links);
- }
-
- /* Add the aliases */
- while (aliases.slh_first != NULL) {
- symbol_node_t *curnode;
- symbol_node_t *regnode;
- char *regname;
-
- curnode = aliases.slh_first;
- SLIST_REMOVE_HEAD(&aliases, links);
-
- regname = curnode->symbol->info.ainfo->parent->name;
- regnode = symlist_search(&registers, regname);
- SLIST_INSERT_AFTER(regnode, curnode, links);
- }
-
- /* Output what we have */
- fprintf(ofile,
-"/*
- * DO NOT EDIT - This file is automatically generated.
- */\n");
- while (registers.slh_first != NULL) {
- symbol_node_t *curnode;
- u_int8_t value;
- char *tab_str;
- char *tab_str2;
-
- curnode = registers.slh_first;
- SLIST_REMOVE_HEAD(&registers, links);
- switch(curnode->symbol->type) {
- case REGISTER:
- case SCBLOC:
- case SRAMLOC:
- fprintf(ofile, "\n");
- value = curnode->symbol->info.rinfo->address;
- tab_str = "\t";
- tab_str2 = "\t\t";
- break;
- case ALIAS:
- {
- symbol_t *parent;
-
- parent = curnode->symbol->info.ainfo->parent;
- value = parent->info.rinfo->address;
- tab_str = "\t";
- tab_str2 = "\t\t";
- break;
- }
- case MASK:
- case BIT:
- value = curnode->symbol->info.minfo->mask;
- tab_str = "\t\t";
- tab_str2 = "\t";
- break;
- default:
- value = 0; /* Quiet compiler */
- tab_str = NULL;
- tab_str2 = NULL;
- stop("symtable_dump: Invalid symbol type "
- "encountered", EX_SOFTWARE);
- break;
- }
- fprintf(ofile, "#define%s%-16s%s0x%02x\n",
- tab_str, curnode->symbol->name, tab_str2,
- value);
- free(curnode);
- }
- fprintf(ofile, "\n\n");
-
- while (constants.slh_first != NULL) {
- symbol_node_t *curnode;
-
- curnode = constants.slh_first;
- SLIST_REMOVE_HEAD(&constants, links);
- fprintf(ofile, "#define\t%-8s\t0x%02x\n",
- curnode->symbol->name,
- curnode->symbol->info.cinfo->value);
- free(curnode);
- }
- }
-}
-
diff --git a/sys/dev/aic7xxx/aicasm_symbol.h b/sys/dev/aic7xxx/aicasm_symbol.h
deleted file mode 100644
index cf8fa0071225a..0000000000000
--- a/sys/dev/aic7xxx/aicasm_symbol.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Aic7xxx SCSI host adapter firmware asssembler symbol table definitions
- *
- * Copyright (c) 1997 Justin T. Gibbs.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice immediately at the beginning of the file, without modification,
- * this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $Id$
- */
-
-#include <sys/queue.h>
-
-typedef enum {
- UNINITIALIZED,
- REGISTER,
- ALIAS,
- SCBLOC,
- SRAMLOC,
- MASK,
- BIT,
- CONST,
- LABEL,
- CONDITIONAL
-}symtype;
-
-typedef enum {
- RO = 0x01,
- WO = 0x02,
- RW = 0x03
-}amode_t;
-
-struct reg_info {
- u_int8_t address;
- int size;
- amode_t mode;
- u_int8_t valid_bitmask;
- int typecheck_masks;
-};
-
-typedef SLIST_HEAD(symlist, symbol_node) symlist_t;
-
-struct mask_info {
- symlist_t symrefs;
- u_int8_t mask;
-};
-
-struct const_info {
- u_int8_t value;
- int define;
-};
-
-struct alias_info {
- struct symbol *parent;
-};
-
-struct label_info {
- int address;
-};
-
-struct cond_info {
- int value;
-};
-
-typedef struct expression_info {
- symlist_t referenced_syms;
- int value;
-} expression_t;
-
-typedef struct symbol {
- char *name;
- symtype type;
- union {
- struct reg_info *rinfo;
- struct mask_info *minfo;
- struct const_info *cinfo;
- struct alias_info *ainfo;
- struct label_info *linfo;
- struct cond_info *condinfo;
- }info;
-} symbol_t;
-
-typedef struct symbol_ref {
- symbol_t *symbol;
- int offset;
-} symbol_ref_t;
-
-typedef struct symbol_node {
- SLIST_ENTRY(symbol_node) links;
- symbol_t *symbol;
-}symbol_node_t;
-
-typedef struct patch {
- STAILQ_ENTRY(patch) links;
- int negative;
- int begin;
- int end;
- int options;
-} patch_t;
-
-void symbol_delete __P((symbol_t *symbol));
-
-void symtable_open __P((void));
-
-void symtable_close __P((void));
-
-symbol_t *
- symtable_get __P((char *name));
-
-symbol_node_t *
- symlist_search __P((symlist_t *symlist, char *symname));
-
-void
- symlist_add __P((symlist_t *symlist, symbol_t *symbol, int how));
-#define SYMLIST_INSERT_HEAD 0x00
-#define SYMLIST_SORT 0x01
-
-void symlist_free __P((symlist_t *symlist));
-
-void symlist_merge __P((symlist_t *symlist_dest, symlist_t *symlist_src1,
- symlist_t *symlist_src2));
-void symtable_dump __P((FILE *ofile));
diff --git a/sys/i386/include/asm.h b/sys/i386/include/asm.h
deleted file mode 100644
index d700579696a4e..0000000000000
--- a/sys/i386/include/asm.h
+++ /dev/null
@@ -1,201 +0,0 @@
-/*-
- * Copyright (c) 1990 The Regents of the University of California.
- * All rights reserved.
- *
- * This code is derived from software contributed to Berkeley by
- * William Jolitz.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * from: @(#)DEFS.h 5.1 (Berkeley) 4/23/90
- * $Id: asm.h,v 1.1 1997/03/09 10:39:15 bde Exp $
- */
-
-#include <sys/cdefs.h>
-
-#ifdef PIC
-#define PIC_PROLOGUE \
- pushl %ebx; \
- call 1f; \
-1: \
- popl %ebx; \
- addl $_GLOBAL_OFFSET_TABLE_+[.-1b],%ebx
-#define PIC_EPILOGUE \
- popl %ebx
-#define PIC_PLT(x) x@PLT
-#define PIC_GOT(x) x@GOT(%ebx)
-#define PIC_GOTOFF(x) x@GOTOFF(%ebx)
-#else
-#define PIC_PROLOGUE
-#define PIC_EPILOGUE
-#define PIC_PLT(x) x
-#define PIC_GOT(x) x
-#define PIC_GOTOFF(x) x
-#endif
-
-/*
- * CNAME and HIDENAME manage the relationship between symbol names in C
- * and the equivalent assembly language names. CNAME is given a name as
- * it would be used in a C program. It expands to the equivalent assembly
- * language name. HIDENAME is given an assembly-language name, and expands
- * to a possibly-modified form that will be invisible to C programs.
- */
-#if defined(__ELF__) /* { */
-#define CNAME(csym) csym
-#define HIDENAME(asmsym) __CONCAT(.,asmsym)
-#else /* } { */
-#define CNAME(csym) __CONCAT(_,csym)
-#define HIDENAME(asmsym) asmsym
-#endif /* } */
-
-
-/* XXX should use align 4,0x90 for -m486. */
-#define _START_ENTRY .text; .align 2,0x90;
-#if 0
-/* Data is not used, except perhaps by non-g prof, which we don't support. */
-#define _MID_ENTRY .data; .align 2; 8:; .long 0; \
- .text; lea 8b,%eax;
-#else
-#define _MID_ENTRY
-#endif
-
-#ifdef PROF
-
-#define ALTENTRY(x) _START_ENTRY \
- .globl CNAME(x); .type CNAME(x),@function; CNAME(x):; \
- _MID_ENTRY \
- call HIDENAME(mcount); jmp 9f
-
-#define ENTRY(x) _START_ENTRY \
- .globl CNAME(x); .type CNAME(x),@function; CNAME(x):; \
- _MID_ENTRY \
- call HIDENAME(mcount); 9:
-
-
-#define ALTASENTRY(x) _START_ENTRY \
- .globl x; .type x,@function; x:; \
- _MID_ENTRY \
- call HIDENAME(mcount); jmp 9f
-
-#define ASENTRY(x) _START_ENTRY \
- .globl x; .type x,@function; x:; \
- _MID_ENTRY \
- call HIDENAME(mcount); 9:
-
-#else /* !PROF */
-
-#define ENTRY(x) _START_ENTRY .globl CNAME(x); .type CNAME(x),@function; \
- CNAME(x):
-#define ALTENTRY(x) ENTRY(x)
-
-#define ASENTRY(x) _START_ENTRY .globl x; .type x,@function; x:
-#define ALTASENTRY(x) ASENTRY(x)
-
-#endif
-
-/*
- * This header is currently only used in lib/msun/i387.
- * Use it to generate code to select between the generic math functions
- * and the i387 ones.
- */
-#undef ENTRY
-#define ANAME(x) CNAME(__CONCAT(__i387_,x))
-#define ASELNAME(x) CNAME(__CONCAT(__arch_select_,x))
-#define AVECNAME(x) CNAME(__CONCAT(__arch_,x))
-#define GNAME(x) CNAME(__CONCAT(__generic_,x))
-
-/* Don't bother profiling this. */
-#ifdef PIC
-#define ARCH_DISPATCH(x) \
- _START_ENTRY; \
- .globl CNAME(x); .type CNAME(x),@function; CNAME(x): ; \
- PIC_PROLOGUE; \
- movl PIC_GOT(AVECNAME(x)),%eax; \
- PIC_EPILOGUE; \
- jmpl *(%eax)
-
-#define ARCH_SELECT(x) _START_ENTRY; \
- .type ASELNAME(x),@function; \
- ASELNAME(x): \
- PIC_PROLOGUE; \
- call PIC_PLT(CNAME(__get_hw_float)); \
- testl %eax,%eax; \
- movl PIC_GOT(ANAME(x)),%eax; \
- jne 8f; \
- movl PIC_GOT(GNAME(x)),%eax; \
- 8: \
- movl PIC_GOT(AVECNAME(x)),%edx; \
- movl %eax,(%edx); \
- PIC_EPILOGUE; \
- jmpl *%eax
-#else /* !PIC */
-#define ARCH_DISPATCH(x) \
- _START_ENTRY; \
- .globl CNAME(x); .type CNAME(x),@function; CNAME(x): ; \
- jmpl *AVECNAME(x)
-
-#define ARCH_SELECT(x) _START_ENTRY; \
- .type ASELNAME(x),@function; \
- ASELNAME(x): \
- call CNAME(__get_hw_float); \
- testl %eax,%eax; \
- movl $ANAME(x),%eax; \
- jne 8f; \
- movl $GNAME(x),%eax; \
- 8: \
- movl %eax,AVECNAME(x); \
- jmpl *%eax
-#endif /* PIC */
-
-#define ARCH_VECTOR(x) .data; .align 2; \
- .globl AVECNAME(x); \
- .type AVECNAME(x),@object; \
- .size AVECNAME(x),4; \
- AVECNAME(x): .long ASELNAME(x)
-
-#ifdef PROF
-
-#define ALTENTRY(x) ENTRY(x); jmp 9f
-#define ENTRY(x) ARCH_VECTOR(x); ARCH_SELECT(x); ARCH_DISPATCH(x); \
- _START_ENTRY; \
- .globl ANAME(x); .type ANAME(x),@function; ANAME(x):; \
- call HIDENAME(mcount); 9:
-
-#else /* !PROF */
-
-#define ALTENTRY(x) ENTRY(x)
-#define ENTRY(x) ARCH_VECTOR(x); ARCH_SELECT(x); ARCH_DISPATCH(x); \
- _START_ENTRY; \
- .globl ANAME(x); .type ANAME(x),@function; ANAME(x):
-
-#endif /* PROF */
-
-#ifndef RCSID
-#define RCSID(a)
-#endif
diff --git a/sys/i386/include/vmparam.h b/sys/i386/include/vmparam.h
index 48b570dd0232a..d26b1c6d43ab3 100644
--- a/sys/i386/include/vmparam.h
+++ b/sys/i386/include/vmparam.h
@@ -36,7 +36,7 @@
* SUCH DAMAGE.
*
* from: @(#)vmparam.h 5.9 (Berkeley) 5/12/91
- * $Id: vmparam.h,v 1.20 1996/04/30 12:02:12 phk Exp $
+ * $Id: vmparam.h,v 1.21 1996/05/02 14:20:07 phk Exp $
*/
@@ -116,4 +116,7 @@
/* virtual sizes (bytes) for various kernel submaps */
#define VM_KMEM_SIZE (32 * 1024 * 1024)
+/* read and exec are the same thing */
+#define VM_PROT_READ_IS_EXEC
+
#endif /* _MACHINE_VMPARAM_H_ */
diff --git a/sys/i386/scsi/aic7xxx.c b/sys/i386/scsi/aic7xxx.c
index bb61ea4a9c292..ed0eb8eb675bf 100644
--- a/sys/i386/scsi/aic7xxx.c
+++ b/sys/i386/scsi/aic7xxx.c
@@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: aic7xxx.c,v 1.81.2.14 1997/03/01 06:53:35 gibbs Exp $
+ * $Id: aic7xxx.c,v 1.81.2.16 1997/03/24 05:11:03 gibbs Exp $
*/
/*
* TODO:
@@ -812,8 +812,7 @@ ahc_intr(arg)
scb->xs->error);
ahc_run_done_queue(ahc);
}
- if (scb->hscb->status != SCSI_QUEUE_FULL)
- ahc_done(ahc, scb);
+ ahc_done(ahc, scb);
}
ahc_outb(ahc, CLRINT, CLRCMDINT);
int_cleared++;
@@ -1334,13 +1333,8 @@ ahc_handle_seqint(ahc, intstat)
/*
* XXX requeue this unconditionally.
*/
- STAILQ_INSERT_TAIL(&ahc->waiting_scbs, scb,
- links);
- scb->flags |= SCB_WAITINGQ;
- /* Give the command a new lease on life */
- untimeout(ahc_timeout, (caddr_t)scb);
- timeout(ahc_timeout, (caddr_t)scb,
- (scb->xs->timeout * hz) / 1000);
+ scb->xs->retries++;
+ scb->xs->error = XS_BUSY;
break;
}
/* Else treat as if it is a BUSY condition */
@@ -2566,7 +2560,12 @@ ahc_run_waiting_queue(ahc)
{
struct scb *scb;
- pause_sequencer(ahc);
+ /*
+ * On aic78X0 chips, we rely on Auto Access Pause (AAP)
+ * instead of doing an explicit pause/unpause.
+ */
+ if ((ahc->type & AHC_AIC78X0) == 0)
+ pause_sequencer(ahc);
while ((scb = ahc->waiting_scbs.stqh_first) != NULL) {
@@ -2588,7 +2587,8 @@ ahc_run_waiting_queue(ahc)
*/
ahc->curqincnt++;
}
- unpause_sequencer(ahc, /*Unpause always*/FALSE);
+ if ((ahc->type & AHC_AIC78X0) == 0)
+ unpause_sequencer(ahc, /*Unpause always*/FALSE);
}
/*
@@ -3185,7 +3185,7 @@ ahc_find_scb(ahc, scb)
break;
}
ahc_outb(ahc, SCBPTR, saved_scbptr);
- if (curindex > ahc->scb_data->maxhscbs)
+ if (curindex >= ahc->scb_data->maxhscbs)
curindex = SCB_LIST_NULL;
return curindex;
diff --git a/sys/miscfs/procfs/procfs_map.c b/sys/miscfs/procfs/procfs_map.c
index b3d6c9bd73b55..d9bbe180852aa 100644
--- a/sys/miscfs/procfs/procfs_map.c
+++ b/sys/miscfs/procfs/procfs_map.c
@@ -36,7 +36,7 @@
*
* @(#)procfs_status.c 8.3 (Berkeley) 2/17/94
*
- * $Id: procfs_map.c,v 1.4 1996/07/27 19:47:04 dyson Exp $
+ * $Id: procfs_map.c,v 1.6 1996/10/30 03:52:57 dyson Exp $
*/
#include <sys/param.h>
@@ -113,7 +113,7 @@ procfs_domap(curp, p, pfs, uio)
int resident, privateresident;
char *type;
- if (entry->is_a_map || entry->is_sub_map)
+ if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP))
continue;
obj = entry->object.vm_object;
@@ -163,7 +163,7 @@ case OBJT_DEVICE:
(entry->protection & VM_PROT_READ)?"r":"-",
(entry->protection & VM_PROT_WRITE)?"w":"-",
(entry->protection & VM_PROT_EXECUTE)?"x":"-",
- entry->copy_on_write?"COW":" ",
+ (entry->eflags & MAP_ENTRY_COW)?"COW":" ",
type);
len = strlen(mebuffer);
diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c
index 2b8eeacd8f099..b4147611536c7 100644
--- a/sys/scsi/scsi_base.c
+++ b/sys/scsi/scsi_base.c
@@ -8,7 +8,7 @@
* file.
*
* Written by Julian Elischer (julian@dialix.oz.au)
- * $Id: scsi_base.c,v 1.39.4.1 1997/01/12 22:09:53 joerg Exp $
+ * $Id: scsi_base.c,v 1.39.4.2 1997/01/30 22:49:29 joerg Exp $
*/
#include "opt_bounce.h"
@@ -615,7 +615,9 @@ retry:
* check if anyone else needs to be started up.
*/
bad:
+ s = splbio();
free_xs(xs, sc_link, flags); /* includes the 'start' op */
+ splx(s);
if (bp && retval) {
bp->b_error = retval;
bp->b_flags |= B_ERROR;
diff --git a/sys/vm/vm_extern.h b/sys/vm/vm_extern.h
index 5a706917de747..3d5a335278528 100644
--- a/sys/vm/vm_extern.h
+++ b/sys/vm/vm_extern.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vm_extern.h 8.2 (Berkeley) 1/12/94
- * $Id: vm_extern.h,v 1.26 1996/09/14 11:54:54 bde Exp $
+ * $Id: vm_extern.h,v 1.27 1996/09/15 11:24:21 bde Exp $
*/
#ifndef _VM_EXTERN_H_
@@ -80,6 +80,7 @@ int vm_fault __P((vm_map_t, vm_offset_t, vm_prot_t, boolean_t));
void vm_fault_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t, vm_map_entry_t));
void vm_fault_unwire __P((vm_map_t, vm_offset_t, vm_offset_t));
int vm_fault_wire __P((vm_map_t, vm_offset_t, vm_offset_t));
+int vm_fault_user_wire __P((vm_map_t, vm_offset_t, vm_offset_t));
int vm_fork __P((struct proc *, struct proc *));
int vm_mmap __P((vm_map_t, vm_offset_t *, vm_size_t, vm_prot_t, vm_prot_t, int, caddr_t, vm_ooffset_t));
vm_offset_t vm_page_alloc_contig __P((vm_offset_t, vm_offset_t, vm_offset_t, vm_offset_t));
diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c
index e7fdd373e34bf..561b496b4ffcd 100644
--- a/sys/vm/vm_fault.c
+++ b/sys/vm/vm_fault.c
@@ -66,7 +66,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_fault.c,v 1.57 1996/09/08 20:44:37 dyson Exp $
+ * $Id: vm_fault.c,v 1.57.2.1 1996/12/15 09:57:11 davidg Exp $
*/
/*
@@ -197,11 +197,37 @@ RetryFault:;
return (result);
}
- if (entry->nofault) {
+ if (entry->eflags & MAP_ENTRY_NOFAULT) {
panic("vm_fault: fault on nofault entry, addr: %lx",
vaddr);
}
+ /*
+ * If we are user-wiring a r/w segment, and it is COW, then
+ * we need to do the COW operation. Note that we don't COW
+ * currently RO sections now, because it is NOT desirable
+ * to COW .text. We simply keep .text from ever being COW'ed
+ * and take the heat that one cannot debug wired .text sections.
+ */
+ if ((change_wiring == VM_FAULT_USER_WIRE) && (entry->eflags & MAP_ENTRY_NEEDS_COPY)) {
+ if(entry->protection & VM_PROT_WRITE) {
+ int tresult;
+ vm_map_lookup_done(map, entry);
+
+ tresult = vm_map_lookup(&map, vaddr, VM_PROT_READ|VM_PROT_WRITE,
+ &entry, &first_object, &first_pindex, &prot, &wired, &su);
+ if (tresult != KERN_SUCCESS)
+ return tresult;
+ } else {
+ /*
+ * If we don't COW now, on a user wire, the user will never
+ * be able to write to the mapping. If we don't make this
+ * restriction, the bookkeeping would be nearly impossible.
+ */
+ entry->max_protection &= ~VM_PROT_WRITE;
+ }
+ }
+
vp = vnode_pager_lock(first_object);
lookup_still_valid = TRUE;
@@ -839,7 +865,48 @@ vm_fault_wire(map, start, end)
*/
for (va = start; va < end; va += PAGE_SIZE) {
- rv = vm_fault(map, va, VM_PROT_READ|VM_PROT_WRITE, TRUE);
+ rv = vm_fault(map, va, VM_PROT_READ|VM_PROT_WRITE,
+ VM_FAULT_CHANGE_WIRING);
+ if (rv) {
+ if (va != start)
+ vm_fault_unwire(map, start, va);
+ return (rv);
+ }
+ }
+ return (KERN_SUCCESS);
+}
+
+/*
+ * vm_fault_user_wire:
+ *
+ * Wire down a range of virtual addresses in a map. This
+ * is for user mode though, so we only ask for read access
+ * on currently read only sections.
+ */
+int
+vm_fault_user_wire(map, start, end)
+ vm_map_t map;
+ vm_offset_t start, end;
+{
+
+ register vm_offset_t va;
+ register pmap_t pmap;
+ int rv;
+
+ pmap = vm_map_pmap(map);
+
+ /*
+ * Inform the physical mapping system that the range of addresses may
+ * not fault, so that page tables and such can be locked down as well.
+ */
+ pmap_pageable(pmap, start, end, FALSE);
+
+ /*
+ * We simulate a fault to get the page and enter it in the physical
+ * map.
+ */
+ for (va = start; va < end; va += PAGE_SIZE) {
+ rv = vm_fault(map, va, VM_PROT_READ, VM_FAULT_USER_WIRE);
if (rv) {
if (va != start)
vm_fault_unwire(map, start, va);
diff --git a/sys/vm/vm_glue.c b/sys/vm/vm_glue.c
index 22091d772737f..71bcb7c67c4b4 100644
--- a/sys/vm/vm_glue.c
+++ b/sys/vm/vm_glue.c
@@ -59,7 +59,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_glue.c,v 1.55.2.1 1996/12/22 23:21:25 joerg Exp $
+ * $Id: vm_glue.c,v 1.55.2.2 1997/02/13 08:17:31 bde Exp $
*/
#include "opt_rlimit.h"
@@ -126,7 +126,9 @@ kernacc(addr, len, rw)
saddr = trunc_page(addr);
eaddr = round_page(addr + len);
+ vm_map_lock_read(kernel_map);
rv = vm_map_check_protection(kernel_map, saddr, eaddr, prot);
+ vm_map_unlock_read(kernel_map);
return (rv == TRUE);
}
@@ -137,6 +139,8 @@ useracc(addr, len, rw)
{
boolean_t rv;
vm_prot_t prot = rw == B_READ ? VM_PROT_READ : VM_PROT_WRITE;
+ vm_map_t map;
+ vm_map_entry_t save_hint;
/*
* XXX - check separately to disallow access to user area and user
@@ -151,8 +155,18 @@ useracc(addr, len, rw)
|| (vm_offset_t) addr + len < (vm_offset_t) addr) {
return (FALSE);
}
- rv = vm_map_check_protection(&curproc->p_vmspace->vm_map,
+ map = &curproc->p_vmspace->vm_map;
+ vm_map_lock_read(map);
+ /*
+ * We save the map hint, and restore it. Useracc appears to distort
+ * the map hint unnecessarily.
+ */
+ save_hint = map->hint;
+ rv = vm_map_check_protection(map,
trunc_page(addr), round_page(addr + len), prot);
+ map->hint = save_hint;
+ vm_map_unlock_read(map);
+
return (rv == TRUE);
}
diff --git a/sys/vm/vm_kern.c b/sys/vm/vm_kern.c
index 21939f6e4da97..c5096cb5c93c8 100644
--- a/sys/vm/vm_kern.c
+++ b/sys/vm/vm_kern.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_kern.c,v 1.27 1996/07/02 02:08:02 dyson Exp $
+ * $Id: vm_kern.c,v 1.27.2.1 1997/01/17 19:28:38 davidg Exp $
*/
/*
@@ -89,17 +89,17 @@
#include <vm/vm_kern.h>
#include <vm/vm_extern.h>
-vm_map_t buffer_map;
-vm_map_t kernel_map;
-vm_map_t kmem_map;
-vm_map_t mb_map;
-int mb_map_full;
-vm_map_t io_map;
-vm_map_t clean_map;
-vm_map_t phys_map;
-vm_map_t exec_map;
-vm_map_t exech_map;
-vm_map_t u_map;
+vm_map_t kernel_map=0;
+vm_map_t kmem_map=0;
+vm_map_t exec_map=0;
+vm_map_t exech_map=0;
+vm_map_t clean_map=0;
+vm_map_t u_map=0;
+vm_map_t buffer_map=0;
+vm_map_t mb_map=0;
+int mb_map_full=0;
+vm_map_t io_map=0;
+vm_map_t phys_map=0;
/*
* kmem_alloc_pageable:
@@ -199,11 +199,6 @@ kmem_alloc(map, size)
(void) vm_map_pageable(map, (vm_offset_t) addr, addr + size, FALSE);
- /*
- * Try to coalesce the map
- */
- vm_map_simplify(map, addr);
-
return (addr);
}
@@ -362,6 +357,8 @@ retry:
panic("kmem_malloc: entry not found or misaligned");
entry->wired_count++;
+ vm_map_simplify_entry(map, entry);
+
/*
* Loop thru pages, entering them in the pmap. (We cannot add them to
* the wired count without wrapping the vm_page_queue_lock in
@@ -377,7 +374,6 @@ retry:
}
vm_map_unlock(map);
- vm_map_simplify(map, addr);
return (addr);
}
diff --git a/sys/vm/vm_map.c b/sys/vm/vm_map.c
index b66b770110fd9..2ec6926b5baf8 100644
--- a/sys/vm/vm_map.c
+++ b/sys/vm/vm_map.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_map.c,v 1.57.2.2 1997/01/26 03:14:59 dyson Exp $
+ * $Id: vm_map.c,v 1.57.2.3 1997/01/31 04:17:20 dyson Exp $
*/
/*
@@ -153,6 +153,7 @@ vm_size_t kentry_data_size;
static vm_map_entry_t kentry_free;
static vm_map_t kmap_free;
extern char kstack[];
+extern int inmprotect;
static int kentry_count;
static vm_offset_t mapvm_start, mapvm, mapvmmax;
@@ -170,7 +171,6 @@ static void vm_map_entry_dispose __P((vm_map_t, vm_map_entry_t));
static void vm_map_entry_unwire __P((vm_map_t, vm_map_entry_t));
static void vm_map_copy_entry __P((vm_map_t, vm_map_t, vm_map_entry_t,
vm_map_entry_t));
-static void vm_map_simplify_entry __P((vm_map_t, vm_map_entry_t));
void
vm_map_startup()
@@ -606,6 +606,7 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow)
register vm_map_entry_t prev_entry;
vm_map_entry_t temp_entry;
vm_object_t prev_object;
+ u_char protoeflags;
if ((object != NULL) && (cow & MAP_NOFAULT)) {
panic("vm_map_insert: paradoxical MAP_NOFAULT request");
@@ -637,48 +638,61 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow)
(prev_entry->next->start < end))
return (KERN_NO_SPACE);
- if ((prev_entry != &map->header) &&
- (prev_entry->end == start) &&
- (object == NULL) &&
- (prev_entry->is_a_map == FALSE) &&
- (prev_entry->is_sub_map == FALSE) &&
- (prev_entry->inheritance == VM_INHERIT_DEFAULT) &&
- (prev_entry->protection == prot) &&
- (prev_entry->max_protection == max) &&
- (prev_entry->wired_count == 0)) {
+ protoeflags = 0;
+ if (cow & MAP_COPY_NEEDED)
+ protoeflags |= MAP_ENTRY_NEEDS_COPY;
+
+ if (cow & MAP_COPY_ON_WRITE)
+ protoeflags |= MAP_ENTRY_COW;
+
+ if (cow & MAP_NOFAULT)
+ protoeflags |= MAP_ENTRY_NOFAULT;
-
/*
* See if we can avoid creating a new entry by extending one of our
- * neighbors.
+ * neighbors. Or at least extend the object.
*/
- u_char needs_copy = (cow & MAP_COPY_NEEDED) != 0;
- u_char copy_on_write = (cow & MAP_COPY_ON_WRITE) != 0;
- u_char nofault = (cow & MAP_NOFAULT) != 0;
-
- if ((needs_copy == prev_entry->needs_copy) &&
- (copy_on_write == prev_entry->copy_on_write) &&
- (nofault == prev_entry->nofault) &&
- (nofault || vm_object_coalesce(prev_entry->object.vm_object,
- OFF_TO_IDX(prev_entry->offset),
- (vm_size_t) (prev_entry->end
- - prev_entry->start),
- (vm_size_t) (end - prev_entry->end)))) {
- /*
- * Coalesced the two objects - can extend the
- * previous map entry to include the new
- * range.
- */
+ if ((object == NULL) &&
+ (prev_entry != &map->header) &&
+ (( prev_entry->eflags & (MAP_ENTRY_IS_A_MAP | MAP_ENTRY_IS_SUB_MAP)) == 0) &&
+ (prev_entry->end == start) &&
+ (prev_entry->wired_count == 0)) {
+
+
+ if ((protoeflags == prev_entry->eflags) &&
+ ((cow & MAP_NOFAULT) ||
+ vm_object_coalesce(prev_entry->object.vm_object,
+ OFF_TO_IDX(prev_entry->offset),
+ (vm_size_t) (prev_entry->end - prev_entry->start),
+ (vm_size_t) (end - prev_entry->end)))) {
+
+ /*
+ * Coalesced the two objects. Can we extend the
+ * previous map entry to include the new range?
+ */
+ if ((prev_entry->inheritance == VM_INHERIT_DEFAULT) &&
+ (prev_entry->protection == prot) &&
+ (prev_entry->max_protection == max)) {
+
map->size += (end - prev_entry->end);
prev_entry->end = end;
- if (!nofault) {
+ if ((cow & MAP_NOFAULT) == 0) {
prev_object = prev_entry->object.vm_object;
default_pager_convert_to_swapq(prev_object);
}
return (KERN_SUCCESS);
}
+ else {
+ object = prev_entry->object.vm_object;
+ offset = prev_entry->offset + (prev_entry->end -
+ prev_entry->start);
+
+ vm_object_reference(object);
+ }
+ }
}
+
/*
* Create a new entry
*/
@@ -687,26 +701,10 @@ vm_map_insert(map, object, offset, start, end, prot, max, cow)
new_entry->start = start;
new_entry->end = end;
- new_entry->is_a_map = FALSE;
- new_entry->is_sub_map = FALSE;
+ new_entry->eflags = protoeflags;
new_entry->object.vm_object = object;
new_entry->offset = offset;
- if (cow & MAP_COPY_NEEDED)
- new_entry->needs_copy = TRUE;
- else
- new_entry->needs_copy = FALSE;
-
- if (cow & MAP_COPY_ON_WRITE)
- new_entry->copy_on_write = TRUE;
- else
- new_entry->copy_on_write = FALSE;
-
- if (cow & MAP_NOFAULT)
- new_entry->nofault = TRUE;
- else
- new_entry->nofault = FALSE;
-
if (map->is_main_map) {
new_entry->inheritance = VM_INHERIT_DEFAULT;
new_entry->protection = prot;
@@ -838,28 +836,19 @@ vm_map_find(map, object, offset, addr, length, find_space, prot, max, cow)
}
/*
- * vm_map_simplify_entry: [ internal use only ]
+ * vm_map_simplify_entry:
*
- * Simplify the given map entry by:
- * removing extra sharing maps
- * [XXX maybe later] merging with a neighbor
+ * Simplify the given map entry by merging with either neighbor.
*/
-static void
+void
vm_map_simplify_entry(map, entry)
vm_map_t map;
vm_map_entry_t entry;
{
vm_map_entry_t next, prev;
- vm_size_t nextsize, prevsize, esize;
-
- /*
- * If this entry corresponds to a sharing map, then see if we can
- * remove the level of indirection. If it's not a sharing map, then it
- * points to a VM object, so see if we can merge with either of our
- * neighbors.
- */
+ vm_size_t prevsize, esize;
- if (entry->is_sub_map || entry->is_a_map || entry->wired_count)
+ if (entry->eflags & (MAP_ENTRY_IS_SUB_MAP|MAP_ENTRY_IS_A_MAP))
return;
prev = entry->prev;
@@ -870,14 +859,11 @@ vm_map_simplify_entry(map, entry)
(!prev->object.vm_object || (prev->object.vm_object->behavior == entry->object.vm_object->behavior)) &&
(!prev->object.vm_object ||
(prev->offset + prevsize == entry->offset)) &&
- (prev->needs_copy == entry->needs_copy) &&
- (prev->copy_on_write == entry->copy_on_write) &&
+ (prev->eflags == entry->eflags) &&
(prev->protection == entry->protection) &&
(prev->max_protection == entry->max_protection) &&
(prev->inheritance == entry->inheritance) &&
- (prev->is_a_map == FALSE) &&
- (prev->is_sub_map == FALSE) &&
- (prev->wired_count == 0)) {
+ (prev->wired_count == entry->wired_count)) {
if (map->first_free == prev)
map->first_free = entry;
if (map->hint == prev)
@@ -893,21 +879,17 @@ vm_map_simplify_entry(map, entry)
next = entry->next;
if (next != &map->header) {
- nextsize = next->end - next->start;
esize = entry->end - entry->start;
if ((entry->end == next->start) &&
(next->object.vm_object == entry->object.vm_object) &&
(!next->object.vm_object || (next->object.vm_object->behavior == entry->object.vm_object->behavior)) &&
(!entry->object.vm_object ||
(entry->offset + esize == next->offset)) &&
- (next->needs_copy == entry->needs_copy) &&
- (next->copy_on_write == entry->copy_on_write) &&
+ (next->eflags == entry->eflags) &&
(next->protection == entry->protection) &&
(next->max_protection == entry->max_protection) &&
(next->inheritance == entry->inheritance) &&
- (next->is_a_map == FALSE) &&
- (next->is_sub_map == FALSE) &&
- (next->wired_count == 0)) {
+ (next->wired_count == entry->wired_count)) {
if (map->first_free == next)
map->first_free = entry;
if (map->hint == next)
@@ -962,7 +944,7 @@ _vm_map_clip_start(map, entry, start)
vm_map_entry_link(map, entry->prev, new_entry);
- if (entry->is_a_map || entry->is_sub_map)
+ if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP))
vm_map_reference(new_entry->object.share_map);
else
vm_object_reference(new_entry->object.vm_object);
@@ -1006,7 +988,7 @@ _vm_map_clip_end(map, entry, end)
vm_map_entry_link(map, entry, new_entry);
- if (entry->is_a_map || entry->is_sub_map)
+ if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP))
vm_map_reference(new_entry->object.share_map);
else
vm_object_reference(new_entry->object.vm_object);
@@ -1068,11 +1050,9 @@ vm_map_submap(map, start, end, submap)
vm_map_clip_end(map, entry, end);
if ((entry->start == start) && (entry->end == end) &&
- (!entry->is_a_map) &&
- (entry->object.vm_object == NULL) &&
- (!entry->copy_on_write)) {
- entry->is_a_map = FALSE;
- entry->is_sub_map = TRUE;
+ ((entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_COW)) == 0) &&
+ (entry->object.vm_object == NULL)) {
+ entry->eflags |= MAP_ENTRY_IS_SUB_MAP;
vm_map_reference(entry->object.sub_map = submap);
result = KERN_SUCCESS;
}
@@ -1106,8 +1086,9 @@ vm_map_protect(map, start, end, new_prot, set_max)
if (vm_map_lookup_entry(map, start, &entry)) {
vm_map_clip_start(map, entry, start);
- } else
+ } else {
entry = entry->next;
+ }
/*
* Make a first pass to check for protection violations.
@@ -1115,7 +1096,7 @@ vm_map_protect(map, start, end, new_prot, set_max)
current = entry;
while ((current != &map->header) && (current->start < end)) {
- if (current->is_sub_map) {
+ if (current->eflags & MAP_ENTRY_IS_SUB_MAP) {
vm_map_unlock(map);
return (KERN_INVALID_ARGUMENT);
}
@@ -1152,11 +1133,11 @@ vm_map_protect(map, start, end, new_prot, set_max)
*/
if (current->protection != old_prot) {
-#define MASK(entry) ((entry)->copy_on_write ? ~VM_PROT_WRITE : \
+#define MASK(entry) (((entry)->eflags & MAP_ENTRY_COW) ? ~VM_PROT_WRITE : \
VM_PROT_ALL)
#define max(a,b) ((a) > (b) ? (a) : (b))
- if (current->is_a_map) {
+ if (current->eflags & MAP_ENTRY_IS_A_MAP) {
vm_map_entry_t share_entry;
vm_offset_t share_end;
@@ -1229,9 +1210,22 @@ vm_map_madvise(map, pmap, start, end, advise)
for(current = entry;
(current != &map->header) && (current->start < end);
current = current->next) {
- if (current->is_a_map || current->is_sub_map) {
+ vm_size_t size = current->end - current->start;
+
+ if (current->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) {
continue;
}
+
+ /*
+ * Create an object if needed
+ */
+ if (current->object.vm_object == NULL) {
+ vm_object_t object;
+ object = vm_object_allocate(OBJT_DEFAULT, OFF_TO_IDX(size));
+ current->object.vm_object = object;
+ current->offset = 0;
+ }
+
vm_map_clip_end(map, current, end);
switch (advise) {
case MADV_NORMAL:
@@ -1252,7 +1246,7 @@ vm_map_madvise(map, pmap, start, end, advise)
{
vm_pindex_t pindex;
int count;
- vm_size_t size = current->end - current->start;
+ size = current->end - current->start;
pindex = OFF_TO_IDX(entry->offset);
count = OFF_TO_IDX(size);
/*
@@ -1268,7 +1262,7 @@ vm_map_madvise(map, pmap, start, end, advise)
{
vm_pindex_t pindex;
int count;
- vm_size_t size = current->end - current->start;
+ size = current->end - current->start;
pindex = OFF_TO_IDX(current->offset);
count = OFF_TO_IDX(size);
vm_object_madvise(current->object.vm_object,
@@ -1341,6 +1335,137 @@ vm_map_inherit(map, start, end, new_inheritance)
}
/*
+ * Implement the semantics of mlock
+ */
+int
+vm_map_user_pageable(map, start, end, new_pageable)
+ register vm_map_t map;
+ register vm_offset_t start;
+ register vm_offset_t end;
+ register boolean_t new_pageable;
+{
+ register vm_map_entry_t entry;
+ vm_map_entry_t start_entry;
+ register vm_offset_t failed = 0;
+ int rv;
+
+ vm_map_lock(map);
+ VM_MAP_RANGE_CHECK(map, start, end);
+
+ if (vm_map_lookup_entry(map, start, &start_entry) == FALSE) {
+ vm_map_unlock(map);
+ return (KERN_INVALID_ADDRESS);
+ }
+
+ if (new_pageable) {
+
+ entry = start_entry;
+ vm_map_clip_start(map, entry, start);
+
+ /*
+ * Now decrement the wiring count for each region. If a region
+ * becomes completely unwired, unwire its physical pages and
+ * mappings.
+ */
+ lock_set_recursive(&map->lock);
+
+ entry = start_entry;
+ while ((entry != &map->header) && (entry->start < end)) {
+ if (entry->eflags & MAP_ENTRY_USER_WIRED) {
+ vm_map_clip_end(map, entry, end);
+ entry->eflags &= ~MAP_ENTRY_USER_WIRED;
+ entry->wired_count--;
+ if (entry->wired_count == 0)
+ vm_fault_unwire(map, entry->start, entry->end);
+ }
+ entry = entry->next;
+ }
+ vm_map_simplify_entry(map, start_entry);
+ lock_clear_recursive(&map->lock);
+ } else {
+
+ /*
+ * Because of the possiblity of blocking, etc. We restart
+ * through the process's map entries from beginning so that
+ * we don't end up depending on a map entry that could have
+ * changed.
+ */
+ rescan:
+
+ entry = start_entry;
+
+ while ((entry != &map->header) && (entry->start < end)) {
+
+ if (entry->eflags & MAP_ENTRY_USER_WIRED) {
+ entry = entry->next;
+ continue;
+ }
+
+ if (entry->wired_count != 0) {
+ entry->wired_count++;
+ entry->eflags |= MAP_ENTRY_USER_WIRED;
+ entry = entry->next;
+ continue;
+ }
+
+ /* Here on entry being newly wired */
+
+ if ((entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) == 0) {
+ int copyflag = entry->eflags & MAP_ENTRY_NEEDS_COPY;
+ if (copyflag && ((entry->protection & VM_PROT_WRITE) != 0)) {
+
+ vm_object_shadow(&entry->object.vm_object,
+ &entry->offset,
+ OFF_TO_IDX(entry->end
+ - entry->start));
+ entry->eflags &= ~MAP_ENTRY_NEEDS_COPY;
+
+ } else if (entry->object.vm_object == NULL) {
+
+ entry->object.vm_object =
+ vm_object_allocate(OBJT_DEFAULT,
+ OFF_TO_IDX(entry->end - entry->start));
+ entry->offset = (vm_offset_t) 0;
+
+ }
+ default_pager_convert_to_swapq(entry->object.vm_object);
+ }
+
+ vm_map_clip_start(map, entry, start);
+ vm_map_clip_end(map, entry, end);
+
+ entry->wired_count++;
+ entry->eflags |= MAP_ENTRY_USER_WIRED;
+
+ /* First we need to allow map modifications */
+ lock_set_recursive(&map->lock);
+ lock_write_to_read(&map->lock);
+
+ rv = vm_fault_user_wire(map, entry->start, entry->end);
+ if (rv) {
+
+ entry->wired_count--;
+ entry->eflags &= ~MAP_ENTRY_USER_WIRED;
+
+ lock_clear_recursive(&map->lock);
+ vm_map_unlock(map);
+
+ (void) vm_map_user_pageable(map, start, entry->start, TRUE);
+ return rv;
+ }
+
+ lock_clear_recursive(&map->lock);
+ vm_map_unlock(map);
+ vm_map_lock(map);
+
+ goto rescan;
+ }
+ }
+ vm_map_unlock(map);
+ return KERN_SUCCESS;
+}
+
+/*
* vm_map_pageable:
*
* Sets the pageability of the specified address
@@ -1467,8 +1592,8 @@ vm_map_pageable(map, start, end, new_pageable)
* point to sharing maps, because we won't
* hold the lock on the sharing map.
*/
- if (!entry->is_a_map && !entry->is_sub_map) {
- int copyflag = entry->needs_copy;
+ if ((entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) == 0) {
+ int copyflag = entry->eflags & MAP_ENTRY_NEEDS_COPY;
if (copyflag &&
((entry->protection & VM_PROT_WRITE) != 0)) {
@@ -1476,7 +1601,7 @@ vm_map_pageable(map, start, end, new_pageable)
&entry->offset,
OFF_TO_IDX(entry->end
- entry->start));
- entry->needs_copy = FALSE;
+ entry->eflags &= ~MAP_ENTRY_NEEDS_COPY;
} else if (entry->object.vm_object == NULL) {
entry->object.vm_object =
vm_object_allocate(OBJT_DEFAULT,
@@ -1568,6 +1693,7 @@ vm_map_pageable(map, start, end, new_pageable)
(void) vm_map_pageable(map, start, failed, TRUE);
return (rv);
}
+ vm_map_simplify_entry(map, start_entry);
}
vm_map_unlock(map);
@@ -1608,7 +1734,7 @@ vm_map_clean(map, start, end, syncio, invalidate)
* Make a first pass to check for holes.
*/
for (current = entry; current->start < end; current = current->next) {
- if (current->is_sub_map) {
+ if (current->eflags & MAP_ENTRY_IS_SUB_MAP) {
vm_map_unlock_read(map);
return (KERN_INVALID_ARGUMENT);
}
@@ -1627,7 +1753,7 @@ vm_map_clean(map, start, end, syncio, invalidate)
for (current = entry; current->start < end; current = current->next) {
offset = current->offset + (start - current->start);
size = (end <= current->end ? end : current->end) - start;
- if (current->is_a_map || current->is_sub_map) {
+ if (current->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) {
register vm_map_t smap;
vm_map_entry_t tentry;
vm_size_t tsize;
@@ -1718,7 +1844,7 @@ vm_map_entry_delete(map, entry)
vm_map_entry_unlink(map, entry);
map->size -= entry->end - entry->start;
- if (entry->is_a_map || entry->is_sub_map) {
+ if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) {
vm_map_deallocate(entry->object.share_map);
} else {
vm_object_deallocate(entry->object.vm_object);
@@ -1915,7 +2041,8 @@ vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
vm_map_t src_map, dst_map;
register vm_map_entry_t src_entry, dst_entry;
{
- if (src_entry->is_sub_map || dst_entry->is_sub_map)
+ if ((dst_entry->eflags|src_entry->eflags) &
+ (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP))
return;
if (src_entry->wired_count == 0) {
@@ -1924,7 +2051,7 @@ vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
* If the source entry is marked needs_copy, it is already
* write-protected.
*/
- if (!src_entry->needs_copy) {
+ if ((src_entry->eflags & MAP_ENTRY_NEEDS_COPY) == 0) {
boolean_t su;
@@ -1957,11 +2084,8 @@ vm_map_copy_entry(src_map, dst_map, src_entry, dst_entry)
src_entry->object.vm_object->type == OBJT_SWAP))
vm_object_collapse(src_entry->object.vm_object);
++src_entry->object.vm_object->ref_count;
- src_entry->copy_on_write = TRUE;
- src_entry->needs_copy = TRUE;
-
- dst_entry->needs_copy = TRUE;
- dst_entry->copy_on_write = TRUE;
+ src_entry->eflags |= (MAP_ENTRY_COW|MAP_ENTRY_NEEDS_COPY);
+ dst_entry->eflags |= (MAP_ENTRY_COW|MAP_ENTRY_NEEDS_COPY);
dst_entry->object.vm_object =
src_entry->object.vm_object;
dst_entry->offset = src_entry->offset;
@@ -2015,14 +2139,14 @@ vmspace_fork(vm1)
old_entry = old_map->header.next;
while (old_entry != &old_map->header) {
- if (old_entry->is_sub_map)
+ if (old_entry->eflags & MAP_ENTRY_IS_SUB_MAP)
panic("vm_map_fork: encountered a submap");
switch (old_entry->inheritance) {
case VM_INHERIT_NONE:
break;
- case VM_INHERIT_SHARE:
+ case VM_INHERIT_SHARE:
/*
* Clone the entry, creating the shared object if necessary.
*/
@@ -2033,13 +2157,13 @@ vmspace_fork(vm1)
old_entry->start));
old_entry->object.vm_object = object;
old_entry->offset = (vm_offset_t) 0;
- } else if (old_entry->needs_copy) {
+ } else if (old_entry->eflags & MAP_ENTRY_NEEDS_COPY) {
vm_object_shadow(&old_entry->object.vm_object,
&old_entry->offset,
OFF_TO_IDX(old_entry->end -
- old_entry->start));
+ old_entry->start));
- old_entry->needs_copy = 0;
+ old_entry->eflags &= ~MAP_ENTRY_NEEDS_COPY;
object = old_entry->object.vm_object;
}
@@ -2077,7 +2201,7 @@ vmspace_fork(vm1)
*new_entry = *old_entry;
new_entry->wired_count = 0;
new_entry->object.vm_object = NULL;
- new_entry->is_a_map = FALSE;
+ new_entry->eflags &= ~MAP_ENTRY_IS_A_MAP;
vm_map_entry_link(new_map, new_map->header.prev,
new_entry);
vm_map_copy_entry(old_map, new_map, old_entry,
@@ -2173,11 +2297,12 @@ RetryLookup:;
entry = tmp_entry;
*out_entry = entry;
}
+
/*
* Handle submaps.
*/
- if (entry->is_sub_map) {
+ if (entry->eflags & MAP_ENTRY_IS_SUB_MAP) {
vm_map_t old_map = map;
*var_map = map = entry->object.sub_map;
@@ -2205,7 +2330,7 @@ RetryLookup:;
* If we don't already have a VM object, track it down.
*/
- su = !entry->is_a_map;
+ su = (entry->eflags & MAP_ENTRY_IS_A_MAP) == 0;
if (su) {
share_map = map;
share_offset = vaddr;
@@ -2237,7 +2362,7 @@ RetryLookup:;
* If the entry was copy-on-write, we either ...
*/
- if (entry->needs_copy) {
+ if (entry->eflags & MAP_ENTRY_NEEDS_COPY) {
/*
* If we want to write the page, we may as well handle that
* now since we've got the sharing map locked.
@@ -2264,7 +2389,7 @@ RetryLookup:;
&entry->offset,
OFF_TO_IDX(entry->end - entry->start));
- entry->needs_copy = FALSE;
+ entry->eflags &= ~MAP_ENTRY_NEEDS_COPY;
lock_write_to_read(&share_map->lock);
} else {
@@ -2333,7 +2458,7 @@ vm_map_lookup_done(map, entry)
* If this entry references a map, unlock it first.
*/
- if (entry->is_a_map)
+ if (entry->eflags & MAP_ENTRY_IS_A_MAP)
vm_map_unlock_read(entry->object.share_map);
/*
@@ -2343,62 +2468,6 @@ vm_map_lookup_done(map, entry)
vm_map_unlock_read(map);
}
-/*
- * Routine: vm_map_simplify
- * Purpose:
- * Attempt to simplify the map representation in
- * the vicinity of the given starting address.
- * Note:
- * This routine is intended primarily to keep the
- * kernel maps more compact -- they generally don't
- * benefit from the "expand a map entry" technology
- * at allocation time because the adjacent entry
- * is often wired down.
- */
-void
-vm_map_simplify(map, start)
- vm_map_t map;
- vm_offset_t start;
-{
- vm_map_entry_t this_entry;
- vm_map_entry_t prev_entry;
-
- vm_map_lock(map);
- if ((vm_map_lookup_entry(map, start, &this_entry)) &&
- ((prev_entry = this_entry->prev) != &map->header) &&
- (prev_entry->end == start) &&
- (prev_entry->object.vm_object == this_entry->object.vm_object) &&
- ((prev_entry->offset + (prev_entry->end - prev_entry->start))
- == this_entry->offset) &&
-
- (map->is_main_map) &&
-
- (prev_entry->is_a_map == FALSE) &&
- (prev_entry->is_sub_map == FALSE) &&
-
- (this_entry->is_a_map == FALSE) &&
- (this_entry->is_sub_map == FALSE) &&
-
- (prev_entry->inheritance == this_entry->inheritance) &&
- (prev_entry->protection == this_entry->protection) &&
- (prev_entry->max_protection == this_entry->max_protection) &&
- (prev_entry->wired_count == this_entry->wired_count) &&
-
- (prev_entry->copy_on_write == this_entry->copy_on_write) &&
- (prev_entry->needs_copy == this_entry->needs_copy)) {
- if (map->first_free == this_entry)
- map->first_free = prev_entry;
- if (map->hint == this_entry)
- SAVE_HINT(map, prev_entry);
- vm_map_entry_unlink(map, this_entry);
- prev_entry->end = this_entry->end;
- if (this_entry->object.vm_object)
- vm_object_deallocate(this_entry->object.vm_object);
- vm_map_entry_dispose(map, this_entry);
- }
- vm_map_unlock(map);
-}
-
#include "opt_ddb.h"
#ifdef DDB
#include <sys/kernel.h>
@@ -2440,12 +2509,12 @@ DB_SHOW_COMMAND(map, vm_map_print)
if (entry->wired_count != 0)
db_printf("wired, ");
}
- if (entry->is_a_map || entry->is_sub_map) {
+ if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) {
db_printf("share=0x%x, offset=0x%x\n",
(int) entry->object.share_map,
(int) entry->offset);
if ((entry->prev == &map->header) ||
- (!entry->prev->is_a_map) ||
+ ((entry->prev->eflags & MAP_ENTRY_IS_A_MAP) == 0) ||
(entry->prev->object.share_map !=
entry->object.share_map)) {
db_indent += 2;
@@ -2457,13 +2526,13 @@ DB_SHOW_COMMAND(map, vm_map_print)
db_printf("object=0x%x, offset=0x%x",
(int) entry->object.vm_object,
(int) entry->offset);
- if (entry->copy_on_write)
+ if (entry->eflags & MAP_ENTRY_COW)
db_printf(", copy (%s)",
- entry->needs_copy ? "needed" : "done");
+ (entry->eflags & MAP_ENTRY_NEEDS_COPY) ? "needed" : "done");
db_printf("\n");
if ((entry->prev == &map->header) ||
- (entry->prev->is_a_map) ||
+ (entry->prev->eflags & MAP_ENTRY_IS_A_MAP) ||
(entry->prev->object.vm_object !=
entry->object.vm_object)) {
db_indent += 2;
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
index e0fde407aa8c4..5c745e7c4459a 100644
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_map.h,v 1.15 1996/07/30 03:08:11 dyson Exp $
+ * $Id: vm_map.h,v 1.15.2.1 1996/12/15 09:57:14 davidg Exp $
*/
/*
@@ -104,11 +104,7 @@ struct vm_map_entry {
vm_offset_t end; /* end address */
union vm_map_object object; /* object I point to */
vm_ooffset_t offset; /* offset into object */
- u_char is_a_map:1, /* Is "object" a map? */
- is_sub_map:1, /* Is "object" a submap? */
- copy_on_write:1, /* is data copy-on-write */
- needs_copy:1, /* does object need to be copied */
- nofault:1; /* should never fault */
+ u_char eflags; /* map entry flags */
/* Only in task maps: */
vm_prot_t protection; /* protection code */
vm_prot_t max_protection; /* maximum protection */
@@ -116,6 +112,13 @@ struct vm_map_entry {
int wired_count; /* can be paged if = 0 */
};
+#define MAP_ENTRY_IS_A_MAP 0x1
+#define MAP_ENTRY_IS_SUB_MAP 0x2
+#define MAP_ENTRY_COW 0x4
+#define MAP_ENTRY_NEEDS_COPY 0x8
+#define MAP_ENTRY_NOFAULT 0x10
+#define MAP_ENTRY_USER_WIRED 0x20
+
/*
* Maps are doubly-linked lists of map entries, kept sorted
* by address. A single hint is provided to start
@@ -210,6 +213,13 @@ typedef struct {
#define MAP_COPY_ON_WRITE 0x2
#define MAP_NOFAULT 0x4
+/*
+ * vm_fault option flags
+ */
+#define VM_FAULT_NORMAL 0
+#define VM_FAULT_CHANGE_WIRING 1
+#define VM_FAULT_USER_WIRE 2
+
#ifdef KERNEL
extern vm_offset_t kentry_data;
extern vm_size_t kentry_data_size;
@@ -230,6 +240,7 @@ int vm_map_lookup __P((vm_map_t *, vm_offset_t, vm_prot_t, vm_map_entry_t *, vm_
void vm_map_lookup_done __P((vm_map_t, vm_map_entry_t));
boolean_t vm_map_lookup_entry __P((vm_map_t, vm_offset_t, vm_map_entry_t *));
int vm_map_pageable __P((vm_map_t, vm_offset_t, vm_offset_t, boolean_t));
+int vm_map_user_pageable __P((vm_map_t, vm_offset_t, vm_offset_t, boolean_t));
int vm_map_clean __P((vm_map_t, vm_offset_t, vm_offset_t, boolean_t, boolean_t));
int vm_map_protect __P((vm_map_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t));
void vm_map_reference __P((vm_map_t));
@@ -238,6 +249,7 @@ void vm_map_simplify __P((vm_map_t, vm_offset_t));
void vm_map_startup __P((void));
int vm_map_submap __P((vm_map_t, vm_offset_t, vm_offset_t, vm_map_t));
void vm_map_madvise __P((vm_map_t, pmap_t, vm_offset_t, vm_offset_t, int));
+void vm_map_simplify_entry __P((vm_map_t, vm_map_entry_t));
#endif
#endif /* _VM_MAP_ */
diff --git a/sys/vm/vm_meter.c b/sys/vm/vm_meter.c
index faed27f801346..54d66789c4180 100644
--- a/sys/vm/vm_meter.c
+++ b/sys/vm/vm_meter.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* @(#)vm_meter.c 8.4 (Berkeley) 1/4/94
- * $Id: vm_meter.c,v 1.15 1996/05/18 03:37:47 dyson Exp $
+ * $Id: vm_meter.c,v 1.16 1996/09/08 20:44:39 dyson Exp $
*/
#include <sys/param.h>
@@ -179,7 +179,7 @@ vmtotal SYSCTL_HANDLER_ARGS
paging = 0;
for (map = &p->p_vmspace->vm_map, entry = map->header.next;
entry != &map->header; entry = entry->next) {
- if (entry->is_a_map || entry->is_sub_map ||
+ if ((entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) ||
entry->object.vm_object == NULL)
continue;
entry->object.vm_object->flags |= OBJ_ACTIVE;
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
index 16a0dfbbce1b0..6d2b9a6a65a50 100644
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -38,7 +38,7 @@
* from: Utah $Hdr: vm_mmap.c 1.6 91/10/21$
*
* @(#)vm_mmap.c 8.4 (Berkeley) 1/12/94
- * $Id: vm_mmap.c,v 1.53 1996/10/29 22:07:11 dyson Exp $
+ * $Id: vm_mmap.c,v 1.53.2.1 1996/12/22 23:21:26 joerg Exp $
*/
/*
@@ -475,6 +475,10 @@ mprotect(p, uap, retval)
addr = (vm_offset_t) uap->addr;
size = uap->len;
prot = uap->prot & VM_PROT_ALL;
+#if defined(VM_PROT_READ_IS_EXEC)
+ if (prot & VM_PROT_READ)
+ prot |= VM_PROT_EXECUTE;
+#endif
pageoff = (addr & PAGE_MASK);
addr -= pageoff;
@@ -648,7 +652,7 @@ mincore(p, uap, retval)
/*
* ignore submaps (for now) or null objects
*/
- if (current->is_a_map || current->is_sub_map ||
+ if ((current->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) ||
current->object.vm_object == NULL)
continue;
@@ -787,7 +791,7 @@ mlock(p, uap, retval)
return (error);
#endif
- error = vm_map_pageable(&p->p_vmspace->vm_map, addr, addr + size, FALSE);
+ error = vm_map_user_pageable(&p->p_vmspace->vm_map, addr, addr + size, FALSE);
return (error == KERN_SUCCESS ? 0 : ENOMEM);
}
@@ -825,7 +829,7 @@ munlock(p, uap, retval)
return (error);
#endif
- error = vm_map_pageable(&p->p_vmspace->vm_map, addr, addr + size, TRUE);
+ error = vm_map_user_pageable(&p->p_vmspace->vm_map, addr, addr + size, TRUE);
return (error == KERN_SUCCESS ? 0 : ENOMEM);
}
@@ -905,9 +909,14 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
type = OBJT_VNODE;
}
}
- object = vm_pager_allocate(type, handle, OFF_TO_IDX(objsize), prot, foff);
- if (object == NULL)
- return (type == OBJT_DEVICE ? EINVAL : ENOMEM);
+
+ if (handle == NULL) {
+ object = NULL;
+ } else {
+ object = vm_pager_allocate(type, handle, OFF_TO_IDX(objsize), prot, foff);
+ if (object == NULL)
+ return (type == OBJT_DEVICE ? EINVAL : ENOMEM);
+ }
/*
* Force device mappings to be shared.
@@ -922,6 +931,14 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
docow = MAP_COPY_ON_WRITE | MAP_COPY_NEEDED;
}
+#if defined(VM_PROT_READ_IS_EXEC)
+ if (prot & VM_PROT_READ)
+ prot |= VM_PROT_EXECUTE;
+
+ if (maxprot & VM_PROT_READ)
+ maxprot |= VM_PROT_EXECUTE;
+#endif
+
rv = vm_map_find(map, object, foff, addr, size, fitit,
prot, maxprot, docow);
@@ -939,7 +956,7 @@ vm_mmap(map, addr, size, prot, maxprot, flags, handle, foff)
/*
* "Pre-fault" resident pages.
*/
- if ((type == OBJT_VNODE) && (map->pmap != NULL)) {
+ if ((type == OBJT_VNODE) && (map->pmap != NULL) && (object != NULL)) {
pmap_object_init_pt(map->pmap, *addr,
object, (vm_pindex_t) OFF_TO_IDX(foff), size, 1);
}
diff --git a/sys/vm/vm_object.c b/sys/vm/vm_object.c
index 3c6ceeb437db7..133d0edcba11e 100644
--- a/sys/vm/vm_object.c
+++ b/sys/vm/vm_object.c
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_object.c,v 1.81 1996/09/14 11:54:57 bde Exp $
+ * $Id: vm_object.c,v 1.82 1996/09/28 03:33:26 dyson Exp $
*/
/*
@@ -681,6 +681,8 @@ vm_object_pmap_remove(object, start, end)
if (p->pindex >= start && p->pindex < end)
vm_page_protect(p, VM_PROT_NONE);
}
+ if ((start == 0) && (object->size == end))
+ object->flags &= ~OBJ_WRITEABLE;
}
/*
@@ -695,7 +697,9 @@ vm_object_madvise(object, pindex, count, advise)
int count;
int advise;
{
- vm_pindex_t end;
+ int s;
+ vm_pindex_t end, tpindex;
+ vm_object_t tobject;
vm_page_t m;
if (object == NULL)
@@ -704,34 +708,60 @@ vm_object_madvise(object, pindex, count, advise)
end = pindex + count;
for (; pindex < end; pindex += 1) {
- m = vm_page_lookup(object, pindex);
+
+relookup:
+ tobject = object;
+ tpindex = pindex;
+shadowlookup:
+ m = vm_page_lookup(tobject, tpindex);
+ if (m == NULL) {
+ if (tobject->type != OBJT_DEFAULT) {
+ continue;
+ }
+
+ tobject = tobject->backing_object;
+ if ((tobject == NULL) || (tobject->ref_count != 1)) {
+ continue;
+ }
+ tpindex += OFF_TO_IDX(tobject->backing_object_offset);
+ goto shadowlookup;
+ }
/*
* If the page is busy or not in a normal active state,
* we skip it. Things can break if we mess with pages
* in any of the below states.
*/
- if (m == NULL || m->busy || (m->flags & PG_BUSY) ||
- m->hold_count || m->wire_count ||
- m->valid != VM_PAGE_BITS_ALL)
+ if (m->hold_count || m->wire_count ||
+ m->valid != VM_PAGE_BITS_ALL) {
continue;
+ }
+
+ if (m->busy || (m->flags & PG_BUSY)) {
+ s = splvm();
+ if (m->busy || (m->flags & PG_BUSY)) {
+ m->flags |= PG_WANTED;
+ tsleep(m, PVM, "madvpw", 0);
+ }
+ splx(s);
+ goto relookup;
+ }
if (advise == MADV_WILLNEED) {
if (m->queue != PQ_ACTIVE)
vm_page_activate(m);
- } else if ((advise == MADV_DONTNEED) ||
- ((advise == MADV_FREE) &&
- ((object->type != OBJT_DEFAULT) &&
- (object->type != OBJT_SWAP)))) {
+ } else if (advise == MADV_DONTNEED) {
vm_page_deactivate(m);
} else if (advise == MADV_FREE) {
+ pmap_clear_modify(VM_PAGE_TO_PHYS(m));
+ m->dirty = 0;
/*
- * Force a demand-zero on next ref
+ * Force a demand zero if attempt to read from swap.
+ * We currently don't handle vnode files correctly,
+ * and will reread stale contents unnecessarily.
*/
if (object->type == OBJT_SWAP)
- swap_pager_dmzspace(object, m->pindex, 1);
- vm_page_protect(m, VM_PROT_NONE);
- vm_page_free(m);
+ swap_pager_dmzspace(tobject, m->pindex, 1);
}
}
}
@@ -853,6 +883,7 @@ vm_object_qcollapse(object)
swap_pager_freespace(backing_object,
backing_object_paging_offset_index + p->pindex, 1);
vm_page_rename(p, object, new_pindex);
+ vm_page_protect(p, VM_PROT_NONE);
p->dirty = VM_PAGE_BITS_ALL;
}
}
@@ -968,7 +999,9 @@ vm_object_collapse(object)
PAGE_WAKEUP(p);
vm_page_free(p);
} else {
+ vm_page_protect(p, VM_PROT_NONE);
vm_page_rename(p, object, new_pindex);
+ p->dirty = VM_PAGE_BITS_ALL;
}
}
}
@@ -1299,13 +1332,18 @@ vm_object_coalesce(prev_object, prev_pindex, prev_size, next_size)
* pages not mapped to prev_entry may be in use anyway)
*/
- if (prev_object->ref_count > 1 ||
- prev_object->backing_object != NULL) {
+ if (prev_object->backing_object != NULL) {
return (FALSE);
}
prev_size >>= PAGE_SHIFT;
next_size >>= PAGE_SHIFT;
+
+ if ((prev_object->ref_count > 1) &&
+ (prev_object->size != prev_pindex + prev_size)) {
+ return (FALSE);
+ }
+
/*
* Remove any pages that may still be in the object from a previous
* deallocation.
@@ -1360,7 +1398,7 @@ _vm_object_in_map(map, object, entry)
}
tmpe = tmpe->next;
}
- } else if (entry->is_sub_map || entry->is_a_map) {
+ } else if (entry->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) {
tmpm = entry->object.share_map;
tmpe = tmpm->header.next;
entcount = tmpm->nentries;
diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c
index d768359259bb4..0c4a001390cd0 100644
--- a/sys/vm/vm_page.c
+++ b/sys/vm/vm_page.c
@@ -34,7 +34,7 @@
* SUCH DAMAGE.
*
* from: @(#)vm_page.c 7.4 (Berkeley) 5/7/91
- * $Id: vm_page.c,v 1.69.2.1 1996/11/09 21:16:08 phk Exp $
+ * $Id: vm_page.c,v 1.69.2.2 1996/11/12 09:10:16 phk Exp $
*/
/*
@@ -98,16 +98,16 @@ static struct pglist *vm_page_buckets; /* Array of buckets */
static int vm_page_bucket_count; /* How big is array? */
static int vm_page_hash_mask; /* Mask for hash function */
-struct pglist vm_page_queue_free[PQ_L2_SIZE];
-struct pglist vm_page_queue_zero[PQ_L2_SIZE];
-struct pglist vm_page_queue_active;
-struct pglist vm_page_queue_inactive;
-struct pglist vm_page_queue_cache[PQ_L2_SIZE];
+struct pglist vm_page_queue_free[PQ_L2_SIZE] = {0};
+struct pglist vm_page_queue_zero[PQ_L2_SIZE] = {0};
+struct pglist vm_page_queue_active = {0};
+struct pglist vm_page_queue_inactive = {0};
+struct pglist vm_page_queue_cache[PQ_L2_SIZE] = {0};
-int no_queue;
+int no_queue=0;
-struct vpgqueues vm_page_queues[PQ_COUNT];
-int pqcnt[PQ_COUNT];
+struct vpgqueues vm_page_queues[PQ_COUNT] = {0};
+int pqcnt[PQ_COUNT] = {0};
static void
vm_page_queue_init(void) {
@@ -142,13 +142,13 @@ vm_page_queue_init(void) {
}
}
-vm_page_t vm_page_array;
-int vm_page_array_size;
-long first_page;
+vm_page_t vm_page_array = 0;
+int vm_page_array_size = 0;
+long first_page = 0;
static long last_page;
static vm_size_t page_mask;
static int page_shift;
-int vm_page_zero_count;
+int vm_page_zero_count = 0;
/*
* map of contiguous valid DEV_BSIZE chunks in a page
@@ -734,7 +734,7 @@ vm_page_alloc(object, pindex, page_req)
{
register vm_page_t m;
struct vpgqueues *pq;
- int queue;
+ int queue, qtype;
int s;
#ifdef DIAGNOSTIC
@@ -835,15 +835,16 @@ vm_page_alloc(object, pindex, page_req)
}
queue = m->queue;
- if (queue == PQ_ZERO)
+ qtype = queue - m->pc;
+ if (qtype == PQ_ZERO)
--vm_page_zero_count;
pq = &vm_page_queues[queue];
TAILQ_REMOVE(pq->pl, m, pageq);
--(*pq->cnt);
--(*pq->lcnt);
- if ((m->queue - m->pc) == PQ_ZERO) {
+ if (qtype == PQ_ZERO) {
m->flags = PG_ZERO|PG_BUSY;
- } else if ((m->queue - m->pc) == PQ_CACHE) {
+ } else if (qtype == PQ_CACHE) {
vm_page_remove(m);
m->flags = PG_BUSY;
} else {
@@ -874,6 +875,26 @@ vm_page_alloc(object, pindex, page_req)
return (m);
}
+void
+vm_wait()
+{
+ int s;
+
+ s = splvm();
+ if (curproc == pageproc) {
+ vm_pageout_pages_needed = 1;
+ tsleep(&vm_pageout_pages_needed, PSWP, "vmwait", 0);
+ } else {
+ if (!vm_pages_needed) {
+ vm_pages_needed++;
+ wakeup(&vm_pages_needed);
+ }
+ tsleep(&cnt.v_free_count, PVM, "vmwait", 0);
+ }
+ splx(s);
+}
+
+
/*
* vm_page_activate:
*
diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c
index c6888bf1c50b9..9a0b87f9680c5 100644
--- a/sys/vm/vm_pageout.c
+++ b/sys/vm/vm_pageout.c
@@ -65,7 +65,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_pageout.c,v 1.86 1996/09/28 03:33:40 dyson Exp $
+ * $Id: vm_pageout.c,v 1.86.2.1 1997/02/13 08:17:32 bde Exp $
*/
/*
@@ -221,6 +221,7 @@ vm_pageout_clean(m, sync)
if (!sync && object->backing_object) {
vm_object_collapse(object);
}
+
mc[vm_pageout_page_count] = m;
pageout_count = 1;
page_base = vm_pageout_page_count;
@@ -517,7 +518,7 @@ vm_pageout_map_deactivate_pages(map, desired)
*/
tmpe = map->header.next;
while (tmpe != &map->header) {
- if ((tmpe->is_sub_map == 0) && (tmpe->is_a_map == 0)) {
+ if ((tmpe->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) == 0) {
obj = tmpe->object.vm_object;
if ((obj != NULL) && (obj->shadow_count <= 1) &&
((bigobj == NULL) ||
@@ -539,7 +540,7 @@ vm_pageout_map_deactivate_pages(map, desired)
while (tmpe != &map->header) {
if (vm_map_pmap(map)->pm_stats.resident_count <= desired)
break;
- if ((tmpe->is_sub_map == 0) && (tmpe->is_a_map == 0)) {
+ if ((tmpe->eflags & (MAP_ENTRY_IS_A_MAP|MAP_ENTRY_IS_SUB_MAP)) == 0) {
obj = tmpe->object.vm_object;
if (obj)
vm_pageout_object_deactivate_pages(map, obj, desired, 0);
@@ -810,10 +811,12 @@ rescan0:
if (vm_pageout_algorithm_lru ||
(m->object->ref_count == 0) || (m->act_count == 0)) {
--page_shortage;
- vm_page_protect(m, VM_PROT_NONE);
- if ((m->dirty == 0) &&
- (m->object->ref_count == 0)) {
- vm_page_cache(m);
+ if (m->object->ref_count == 0) {
+ vm_page_protect(m, VM_PROT_NONE);
+ if (m->dirty == 0)
+ vm_page_cache(m);
+ else
+ vm_page_deactivate(m);
} else {
vm_page_deactivate(m);
}
@@ -1013,6 +1016,15 @@ vm_pageout()
}
}
+void
+pagedaemon_wakeup()
+{
+ if (!vm_pages_needed && curproc != pageproc) {
+ vm_pages_needed++;
+ wakeup(&vm_pages_needed);
+ }
+}
+
#if !defined(NO_SWAPPING)
static void
vm_req_vmdaemon()
diff --git a/sys/vm/vm_pageout.h b/sys/vm/vm_pageout.h
index f17720b778d11..469482910baa7 100644
--- a/sys/vm/vm_pageout.h
+++ b/sys/vm/vm_pageout.h
@@ -61,7 +61,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
- * $Id: vm_pageout.h,v 1.16 1995/11/20 12:19:22 phk Exp $
+ * $Id: vm_pageout.h,v 1.17 1995/11/21 12:55:26 bde Exp $
*/
#ifndef _VM_VM_PAGEOUT_H_
@@ -91,38 +91,9 @@ extern int vm_pageout_pages_needed;
* Signal pageout-daemon and wait for it.
*/
-static void pagedaemon_wakeup __P((void));
-static inline void
-pagedaemon_wakeup()
-{
- if (!vm_pages_needed && curproc != pageproc) {
- vm_pages_needed++;
- wakeup(&vm_pages_needed);
- }
-}
-
+extern void pagedaemon_wakeup __P((void));
#define VM_WAIT vm_wait()
-
-static void vm_wait __P((void));
-static inline void
-vm_wait()
-{
- int s;
-
- s = splhigh();
- if (curproc == pageproc) {
- vm_pageout_pages_needed = 1;
- tsleep(&vm_pageout_pages_needed, PSWP, "vmwait", 0);
- } else {
- if (!vm_pages_needed) {
- vm_pages_needed++;
- wakeup(&vm_pages_needed);
- }
- tsleep(&cnt.v_free_count, PVM, "vmwait", 0);
- }
- splx(s);
-}
-
+extern void vm_wait __P((void));
#ifdef KERNEL
void vm_pageout_page __P((vm_page_t, vm_object_t));
diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c
index 7581086d71830..3badd6ee8e3b4 100644
--- a/sys/vm/vnode_pager.c
+++ b/sys/vm/vnode_pager.c
@@ -38,7 +38,7 @@
* SUCH DAMAGE.
*
* from: @(#)vnode_pager.c 7.5 (Berkeley) 4/20/91
- * $Id: vnode_pager.c,v 1.64 1996/09/10 05:28:23 dyson Exp $
+ * $Id: vnode_pager.c,v 1.65 1996/10/17 02:49:35 dyson Exp $
*/
/*
@@ -148,6 +148,8 @@ vnode_pager_alloc(handle, size, prot, offset)
else
object->flags = 0;
+ if (vp->v_usecount == 0)
+ panic("vnode_pager_alloc: no vnode reference");
/*
* Hold a reference to the vnode and initialize object data.
*/