You can subscribe to this list here.
2000 |
Jan
|
Feb
|
Mar
(9) |
Apr
(27) |
May
(5) |
Jun
(8) |
Jul
(50) |
Aug
(286) |
Sep
(2) |
Oct
(43) |
Nov
(4) |
Dec
(12) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2001 |
Jan
(79) |
Feb
(102) |
Mar
(29) |
Apr
(2) |
May
(22) |
Jun
(41) |
Jul
(11) |
Aug
(28) |
Sep
(58) |
Oct
(4) |
Nov
(18) |
Dec
(8) |
2002 |
Jan
(2) |
Feb
(2) |
Mar
(1) |
Apr
(478) |
May
(469) |
Jun
(78) |
Jul
(16) |
Aug
(2) |
Sep
(7) |
Oct
(47) |
Nov
(5) |
Dec
(227) |
2003 |
Jan
(155) |
Feb
(188) |
Mar
(160) |
Apr
(172) |
May
(41) |
Jun
(205) |
Jul
(104) |
Aug
(289) |
Sep
(31) |
Oct
|
Nov
|
Dec
|
2004 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Andy P. <at...@us...> - 2001-08-21 20:09:37
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv23019 Modified Files: fault.c pgalloc.c Log Message: Bit more debugging in fault.c, change pgalloc.c to handle slot sizes properly, and fix stupid p1 section page table bug. Index: fault.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/fault.c,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- fault.c 2001/08/20 21:29:07 1.9 +++ fault.c 2001/08/21 20:09:34 1.10 @@ -123,7 +123,12 @@ up(&mm->mmap_sem); if (user_mode(regs)) { + printk(KERN_ALERT "Unable to do USER paging request: " + "pid %d, virtual address %08lx, reason mask %08x, " + "PC %08x, PSL %08x\n", + current->pid, address, reason, info->pc, info->psl); printk("do_page_fault: sending SIGSEGV\n"); + force_sig(SIGSEGV, current); /* signals arent implemented yet */ /* They are now atp aug 17 2001 */ Index: pgalloc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/pgalloc.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- pgalloc.c 2001/08/20 21:29:07 1.3 +++ pgalloc.c 2001/08/21 20:09:34 1.4 @@ -2,12 +2,16 @@ * * pgalloc.c Routines from include/asm-vax/mm/pgalloc.h * Allocation of page table entries and so forth. + * + * This is the main part of the VAX specific memory layer. * * Copyright atp Jun 2001 - complete rewrite. - * atp aug 2001 - add in stuff for vmalloc to work (pmd_alloc_kernel) - * fix mistake in pte_alloc_kernel. - * GNU GPL -*/ + * atp aug 2001 - add in stuff for vmalloc to work (pmd_alloc_kernel) + * fix mistake in pte_alloc_kernel. + * atp 21 aug 01 - make TASK_WSMAX what was intended, add in segv stuff. + * + * License: GNU GPL + */ #include <linux/sched.h> #include <linux/mm.h> @@ -73,7 +77,7 @@ /* this comes in handy later */ ret[0].slot = taskslot; /* p1br points at what would be page mapping 0x40000000 (i.e. the _end_ of the slot)*/ - ret[1].br = taskslot+ (P1PTE_OFFSET) /*+ (N_HWPTE_TASK_P1<<2)*/ - 0x800000 ; + ret[1].br = taskslot+ (P1PTE_OFFSET) - 0x800000 ; /* This is the unmapped number of PTEs */ ret[1].lr = 0x40000; ret[1].slot = taskslot; @@ -289,7 +293,7 @@ /* sanity checks */ if (!s0addr) { - printk(KERN_ERR "VAXMM: null S0 address in remap_and_clear_pte_page!\n"); + vaxpanic(KERN_ERR "VAXMM: null S0 address in remap_and_clear_pte_page!\n"); return; } /* locate the S0 pte that describes the page pointed to by s0addr */ @@ -299,8 +303,7 @@ set_pte(s0pte, pte_mkinvalid(*s0pte)); // print_pte(s0pte); /* FIXME: these flush_tlb_alls need replacing with flush_tlb_8 */ - flush_tlb_all(); - + flush_tlb_all(); // __flush_tlb_one(s0addr); } @@ -451,10 +454,16 @@ /* enforce wsmax memory limits */ if (is_p1){ adjusted_address |= 0x40000000; - if (adjusted_address <= (PAGE_OFFSET-TASK_STKMAX)) goto give_segv; + if (adjusted_address <= (PAGE_OFFSET-TASK_STKMAX)) { + printk(KERN_NOTICE "VAXMM: process %p exceeded TASK_STKMAX (%dMB)\n",current,(TASK_STKMAX>>10)); + goto give_segv; + } pte_number = (adjusted_address - 0x40000000) >> PAGE_SHIFT; } else { - if (adjusted_address >= (TASK_WSMAX+TASK_MMAPMAX)) goto give_segv; + if (adjusted_address >= (TASK_WSMAX)) { + printk(KERN_NOTICE "VAXMM: process %p exceeded TASK_WSMAX (%dMB)\n",current,(TASK_WSMAX>>10)); + goto give_segv; + } pte_number = (adjusted_address>>PAGE_SHIFT); } @@ -531,7 +540,7 @@ return pte_offset(pmd, adjusted_address); give_segv: - printk(KERN_ERR "pte_alloc: sending SIGSEGV to process %p\n",current); + printk(KERN_NOTICE "VAXMM pte_alloc: sending SIGSEGV to process %p\n",current); force_sig(SIGSEGV,current); return NULL; |
From: Andy P. <at...@us...> - 2001-08-21 20:06:45
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv22254 Modified Files: setup.c Log Message: align memory regions to 4k boundaries before feeding to free_bootmem. kernel start and end are not guaranteed to be on 4k pages.. Index: setup.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/setup.c,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- setup.c 2001/08/20 21:32:36 1.11 +++ setup.c 2001/08/21 20:06:42 1.12 @@ -68,7 +68,7 @@ * atp -- have a temporary one. * Shouldn't we use strcpy here? */ - memcpy(command_line, "root=/dev/nfs nfsroot=/tftpboot/vaxroot rw debug\0",63); + memcpy(command_line, "root=/dev/nfs nfsroot=/tftpboot/vaxroot rw debug\0",55); *cmdline_p = command_line; /* Save unparsed command line copy for /proc/cmdline */ memcpy(saved_command_line, command_line, COMMAND_LINE_SIZE); @@ -92,22 +92,31 @@ at the start of physical memory. init_bootmem() also marks every page as reserved. We have to explicitly free available memory ourselves. (max_pfn comes from RPB.) */ - bootmap_size = init_bootmem(0, max_pfn); + +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) +#define PAGEALIGNUP(x) (((x) + PAGE_SIZE-1) & ~(PAGE_SIZE-1)) +#define PAGEALIGNDN(x) ((x) & ~(PAGE_SIZE-1)) +#define PFN_DOWN(x) ((x) >> PAGE_SHIFT) + + bootmap_size = init_bootmem(0, max_pfn); printk("bootmap size = %8.8x\n", bootmap_size); + /* Available memory is now the region from the end of the bootmem bitmap to the start of the kernel and from the end of the SPT to the end of memory */ - region_start = bootmap_size; - region_len = KERNEL_START_PHYS - bootmap_size; + + region_start = PAGEALIGNUP(bootmap_size); + region_len = PAGEALIGNDN(KERNEL_START_PHYS) - region_start; printk("calling free_bootmem(start=%08lx, len=%08lx)\n", region_start, region_len); free_bootmem(region_start, region_len); + - region_start = __pa(SPT_BASE + SPT_SIZE); - region_len = (max_pfn << PAGE_SHIFT) - __pa(SPT_BASE + SPT_SIZE); + region_start = PAGEALIGNUP(__pa(SPT_BASE + SPT_SIZE)); + region_len = PAGEALIGNDN((max_pfn << PAGE_SHIFT)) - region_start; printk("calling free_bootmem(start=%08lx, len=%08lx)\n", region_start, region_len); |
From: Andy P. <at...@us...> - 2001-08-20 21:34:51
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv25267/mm Modified Files: pgalloc.h Log Message: pgalloc pmd_alloc_kernel and free now in pgalloc.c irq.h change call proto for register_excep_handler processor.h eliminate fixme and change pages allocated for task Index: pgalloc.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pgalloc.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- pgalloc.h 2001/07/31 17:33:26 1.9 +++ pgalloc.h 2001/08/20 21:34:48 1.10 @@ -19,6 +19,7 @@ * * atp Jun 2001 remove fixed size processes, use 3 level page table and pte slots. * atp Jun-Jul 2001 - complete rewrite. + * atp Aug 2001 - swapping and vmalloc need pmd_alloc_kernel * * each 'pgd' spans an address range of 0x40000000 bytes. * each page of 'ptes' spans an address range of 0x80000 bytes @@ -100,6 +101,8 @@ /* in arch/vax/mm/pgalloc.c */ extern pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address); extern void pmd_free(pmd_t *pmd); +extern pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address); +extern void pmd_free_kernel(pmd_t *pmd); extern void pte_free(pte_t *pte); extern unsigned long get_pageaddr_from_pte(pte_t *ptep); @@ -138,15 +141,6 @@ #define pte_free_kernel(pte) free_pte_fast(pte) #define pgd_free(pgd) free_pgd_fast(pgd) - - -/* - * allocating and freeing a pmd is trivial: the 1-entry pmd is - * inside the pgd, so has no extra memory associated with it. - */ -#define pmd_free_kernel pmd_free -#define pmd_alloc_kernel pmd_alloc - /* atp jun 01, moved these to arch/vax/mm/pgalloc.c */ /* Allocate a new page for a page table for the kernel */ |
From: Andy P. <at...@us...> - 2001-08-20 21:34:51
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax In directory usw-pr-cvs1:/tmp/cvs-serv25267 Modified Files: processor.h irq.h Log Message: pgalloc pmd_alloc_kernel and free now in pgalloc.c irq.h change call proto for register_excep_handler processor.h eliminate fixme and change pages allocated for task Index: processor.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/processor.h,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- processor.h 2001/07/31 17:33:26 1.9 +++ processor.h 2001/08/20 21:34:48 1.10 @@ -1,6 +1,14 @@ #ifndef _VAX_PROCESSOR_H #define _VAX_PROCESSOR_H +/* Copyright atp 1998-2001. + * kenn 1999-2001. + * + * processor.h for vax architecture. + * + * Aug 2001. atp fix size of task structure allocation + remove fixme comment + */ + #include <asm/pcb.h> /* process control block definition */ #include <asm/page.h> @@ -68,10 +76,6 @@ #define THREAD_SIZE (8192) - - - - /* * Do necessary setup to start up a newly executed thread. */ @@ -131,10 +135,9 @@ machines. See arch/i386/kernel/process.c for the implementation of this. */ -/* FIXME: change the page order from 4 to 1 once the pagelet stuff is done */ #define alloc_task_struct() \ - ((struct task_struct *) __get_free_pages(GFP_KERNEL,4)) -#define free_task_struct(p) free_pages((unsigned long)(p),4) + ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) +#define free_task_struct(p) free_pages((unsigned long)(p),1) #define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) #define init_task (init_task_union.task) Index: irq.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/irq.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- irq.h 2001/07/31 17:33:26 1.3 +++ irq.h 2001/08/20 21:34:48 1.4 @@ -47,6 +47,7 @@ /* This function registers the handler for an exception. */ int register_excep_handler(unsigned int vec_num, + char *exception_name, void (*handler)(struct pt_regs *, void *), unsigned int excep_info_size, unsigned int use_interrupt_stack); |
From: Andy P. <at...@us...> - 2001-08-20 21:32:39
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv25010 Modified Files: setup.c Log Message: fix call to cpu_type_str - its a function. Index: setup.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/setup.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- setup.c 2001/07/31 17:28:26 1.10 +++ setup.c 2001/08/20 21:32:36 1.11 @@ -45,7 +45,7 @@ "cpu sidex\t\t: %d\n" "page size\t\t: %ld\n" "BogoMIPS\t\t: %lu.%02lu\n", - (char *)mv->cpu_type_str, + (char *)mv->cpu_type_str(), /* mv->sidex */ 0x0, PAGE_SIZE, |
From: Andy P. <at...@us...> - 2001-08-20 21:30:54
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv24293 Modified Files: interrupt.c regdump.c Log Message: add vaxpanic convenience function and fix machine check handler and get_irq_list null deferences Index: interrupt.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/interrupt.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- interrupt.c 2001/08/19 10:32:57 1.14 +++ interrupt.c 2001/08/20 21:30:52 1.15 @@ -99,55 +99,78 @@ flush_icache(); } -void trap_init(void) + +/* register the machine check handler. */ +void register_mcheck_handler(void) { extern void machine_check_handler(void); - void *mhandler; + struct irqvector *vector; + unsigned char *inside_vec; + + /* first register things properly so that the irq functions dont get upset */ + if (register_excep_handler(SCB_MCHECK, "Machine Check (machine_check_handler)", machine_check_handler, 2, 1)) { + printk("Panic: unable to register machine check handler\n"); + machine_halt(); + } + + /* Install the specific machine check handler in entry.S + * We override the value set up above, in register_excep_handler, as + * its easier than special casing all the exception info sizing. + */ + inside_vec = (unsigned char *) ((unsigned long)(SCB_VECTOR(SCB_MCHECK)) & ~0x3); + vector = (struct irqvector *)(inside_vec - + offsetof(struct irqvector, inst_jsb)); + vector->dest_addr = machine_check_handler; +} +void trap_init(void) +{ + /* Initialize the SCB with the stray interrupt/exception handlers. Some of these will be overridden later as device drivers hook up to their interrupts. */ setup_scb(); - /* Install the specific machine check handler in entry.S - * bits 0-1 must contain 1. machine check handler is longword aligned - */ - mhandler = (void *)(machine_check_handler) + 1; - scb.scb.mcheck = mhandler; /* And tell the hardware to use this SCB */ __mtpr(__pa(&scb), PR_SCBB); - - /* Register the access violation, page fault, corrected + + /* register the machine check handler. This is a special case due to + * the machine specific exception info which is not fixed sized */ + register_mcheck_handler(); + + /* Register the access violation, page fault, corrected read and other standard exception handlers */ - if (register_excep_handler(SCB_ACCVIO, page_fault_handler, 2, 0)) { + + + if (register_excep_handler(SCB_ACCVIO, "access violation (page_fault_handler)", page_fault_handler, 2, 0)) { printk("Panic: unable to register access violation handler\n"); machine_halt(); } - if (register_excep_handler(SCB_TRANS_INVAL, page_fault_handler, 2, 0)) { + if (register_excep_handler(SCB_TRANS_INVAL, "translation not valid (page_fault_handler)", page_fault_handler, 2, 0)) { printk("Panic: unable to register page fault handler\n"); machine_halt(); } - if (register_excep_handler(SCB_RESOP, reserved_operand_handler, 0, 0)) { + if (register_excep_handler(SCB_RESOP, "reserved operand (reserved_operand_handler)", reserved_operand_handler, 0, 0)) { printk("Panic: unable to register reserved operand handler\n"); machine_halt(); } - if (register_excep_handler(SCB_RESINSTR, reserved_instr_handler, 0, 0)) { + if (register_excep_handler(SCB_RESINSTR, "reserved instruction (reserved_instr_handler)", reserved_instr_handler, 0, 0)) { printk("Panic: unable to register reserved operand handler\n"); machine_halt(); } - if (register_excep_handler(SCB_CHMK, syscall_handler, 1, 0)) { + if (register_excep_handler(SCB_CHMK,"CHMK trap (syscall_handler)", syscall_handler, 1, 0)) { printk("Panic: unable to register syscall handler\n"); machine_halt(); } /* Perhaps this should be done in CPU-specific code? */ - if (register_excep_handler(SCB_MEMCORR, corrected_read_handler, 0, 0)) { + if (register_excep_handler(SCB_MEMCORR,"memory corrected read (corrected_read_handler)", corrected_read_handler, 0, 0)) { printk("Panic: unable to register corrected read handler\n"); machine_halt(); } @@ -595,6 +618,7 @@ } int register_excep_handler(unsigned int vec_num, + char *exception_name, void (*handler)(struct pt_regs *, void *), unsigned int excep_info_size, unsigned int use_interrupt_stack) @@ -619,8 +643,11 @@ vector->excep_info_size = excep_info_size; vector->excep_handler = handler; - + vector->action.name = exception_name; /* needed to stop get_irq_list dying */ + /* FIXME: this doesnt set dev_id or other members of the irqaction structure .. */ + retval = hook_scb_vector(vec_num, vector, use_interrupt_stack); + if (retval) #ifdef KMALLOC_WORKS @@ -638,10 +665,9 @@ struct irqvector *vector; unsigned char *inside_vec; - printk("get irq list: \n"); +// printk("get irq list: \n"); for (i=0; i<NR_IRQS; i++) { - printk("\t%d: scb free %d\n",i,scb_vec_free(i)); if (!scb_vec_free(i)) { inside_vec = SCB_VECTOR(i); @@ -653,8 +679,10 @@ vector = (struct irqvector *)(inside_vec - offsetof(struct irqvector, inst_jsb)); + if (vector->action.name == NULL) + len += sprintf(buf+len, "%4d: %8d no interrupt vector name\n", vector->vec_num, 0); + else len += sprintf(buf+len, "%4d: %8d %s\n", vector->vec_num, 0, vector->action.name); - printk("%4d: %8d %s, len %d\n", vector->vec_num, 0, vector->action.name, len); } } return len; Index: regdump.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/regdump.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- regdump.c 2001/01/29 00:57:00 1.2 +++ regdump.c 2001/08/20 21:30:52 1.3 @@ -229,3 +229,14 @@ show_regs(®s); } +/* little convenience function -- temporary debugging aid - atp */ +void vaxpanic(char *reason) +{ + if (reason) printk(KERN_CRIT "panic: %s\n",reason); + + printk(KERN_CRIT "\nStack dump\n"); + hex_dump((void *)__mfpr(PR_KSP), 256); + dump_cur_regs(1); /* us and parent */ + show_cpu_regs(); + machine_halt(); +} |
From: Andy P. <at...@us...> - 2001-08-20 21:29:11
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv23775 Modified Files: init.c fault.c pgalloc.c Log Message: fix vmalloc handling pte_alloc_kernel and kernel pmd Index: init.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/init.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- init.c 2001/07/31 17:28:26 1.15 +++ init.c 2001/08/20 21:29:07 1.16 @@ -36,6 +36,7 @@ context in task 0. */ pgd_t swapper_pg_dir[PTRS_PER_PGD]; +pmd_t swapper_pm_dir[2048]; /* two pages for the kernel pmd */ /* * In other architectures, paging_init sets up the kernel's page tables. @@ -50,7 +51,13 @@ /* sort out page table. */ pg0 = (pte_t *)SPT_BASE; - + + /* set up pmd */ + swapper_pg_dir[2].pmd = swapper_pm_dir; + swapper_pg_dir[2].pmd2 = &swapper_pm_dir[1024]; + /* FIXME: I _really_ dont like this flag. */ + pmd_val(swapper_pm_dir[PGD_SPECIAL]) = (unsigned long)swapper_pg_dir | 0x1; + /* FIXME: This is where the VMALLOC stuff from head.S should go */ printk("VAXMM: Initialising mm layer for %d tasks of size %dMB\n",TASK_MAXUPRC,(TASK_WSMAX>>20)); Index: fault.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/fault.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- fault.c 2001/08/17 20:20:41 1.8 +++ fault.c 2001/08/20 21:29:07 1.9 @@ -121,10 +121,6 @@ */ bad_area: up(&mm->mmap_sem); - printk("\nStack dump\n"); - hex_dump((void *)(regs->r1), 256); - show_regs(regs); - show_cpu_regs(); if (user_mode(regs)) { printk("do_page_fault: sending SIGSEGV\n"); Index: pgalloc.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/pgalloc.c,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- pgalloc.c 2001/07/31 17:28:26 1.2 +++ pgalloc.c 2001/08/20 21:29:07 1.3 @@ -3,8 +3,9 @@ * pgalloc.c Routines from include/asm-vax/mm/pgalloc.h * Allocation of page table entries and so forth. * - * Copyright atp Jun 2001 - complete rewrite. - * + * Copyright atp Jun 2001 - complete rewrite. + * atp aug 2001 - add in stuff for vmalloc to work (pmd_alloc_kernel) + * fix mistake in pte_alloc_kernel. * GNU GPL */ @@ -15,6 +16,8 @@ #include <asm/pgalloc.h> #include <asm/mmu_context.h> +extern void vaxpanic(char *reason); + #undef VAX_MM_PGALLOC_DEBUG /* @@ -69,8 +72,8 @@ ret[0].lr = 0x0; /* this comes in handy later */ ret[0].slot = taskslot; - /* p1br points at what would be page mapping 0x40000000 */ - ret[1].br = taskslot+ (P1PTE_OFFSET) - 0x800000 ; + /* p1br points at what would be page mapping 0x40000000 (i.e. the _end_ of the slot)*/ + ret[1].br = taskslot+ (P1PTE_OFFSET) /*+ (N_HWPTE_TASK_P1<<2)*/ - 0x800000 ; /* This is the unmapped number of PTEs */ ret[1].lr = 0x40000; ret[1].slot = taskslot; @@ -122,7 +125,10 @@ unsigned long adjaddr; is_p1 = pgd->segment; - adjaddr = (address >> PMD_SHIFT) & (PTRS_PER_PMD - 1); + adjaddr = pmd_index(address); +#ifdef VAX_MM_PGALLOC_DEBUG + printk(KERN_DEBUG "VAXMM: Calling pmd_alloc with (pgd=%8p,pmd=%8lx,address %8lx, adjaddr %8lx)\n",pgd,pgd->pmd,address,adjaddr); +#endif /* sanity check */ /* FIXME: is this pgd_none? */ @@ -190,6 +196,22 @@ return (pmd_t *) pgd->pmd+adjaddr; } +/* the kernel pmd is in mm/init.c */ +extern pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address) +{ + /* we rely on init.c to set up the pmd pointers in the pgd for us. + * This leaves us just a pmd_offset sort of job */ +#ifdef VAX_MM_PGALLOC_DEBUG + printk(KERN_DEBUG "VAXMM: pmd_alloc_kernel: pgd %8p, pgd->pmd %8lx, address %8lx\n",pgd,pgd->pmd,address); +#endif + return pmd_offset(pgd, address); +} + +extern void pmd_free_kernel(pmd_t *pmd) +{ + return; +} + /* This inverts the remapping done in remap_and_clear */ unsigned long get_pageaddr_from_pte(pte_t *ptep) { @@ -232,11 +254,11 @@ /* sanity checks */ if (!s0addr) { - printk(KERN_ERR "VAXMM: null S0 address in remap_and_clear_pte_page!\n"); + vaxpanic("VAXMM: null S0 address in remap_and_clear_pte_page!\n"); return; } if (!pte_page) { - printk(KERN_ERR "VAXMM: null pte_page in remap_and_clear_pte_page!\n"); + vaxpanic("VAXMM: null pte_page in remap_and_clear_pte_page!\n"); return; } @@ -332,18 +354,38 @@ * * - Indeed, however, the implementation is still not obvious to me. * atp July 2001. + * - let me qualify that. pte_alloc_kernel is called infrequently. + * Mostly by the VMALLOC stuff, which already has a VMALLOC_END check. + * so the only reason for calling this is if we are in the middle of + * some operation, outside of the vmalloc family, mapping system space. + * Hence the current implementation suffices, and I cant see a reason + * to implement an expandable s0 page table. */ pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address) { - pgd_t *pgdptr = (pgd_t *)pmd; - - /* note the lr in the system pgd is in PAGELETS.... shift it down to - give page view */ -//printk("pte_allock: pmd, %p, address %8lx\n",pmd,address); - if ((address >> PAGE_SHIFT) < (pgdptr->lr>>3)) - return pte_offset(pmd, address); + pgd_t *pgdptr = (pgd_t *)&swapper_pg_dir[2]; + unsigned long int adjusted_address; + unsigned long int spt_entry; + pte_t *spte; + + adjusted_address = ((pmd - (pmd_t *)(pgdptr->pmd))<<(PAGE_SHIFT+7)) + (address&~PMD_MASK); +#ifdef VAX_MM_PGALLOC_DEBUG + printk(KERN_DEBUG "VAXMM:pte_alloc_kernel: pmd, %p, address %8lx, adjaddr %8lx\n",pmd,address,adjusted_address); +#endif + + /* note the lr in the system pgd is in PAGELETS */ + if (((adjusted_address) >> PAGELET_SHIFT) < (pgdptr->lr)) { + /* fill in any bits missing. Perhaps we should do this when we set up the + * SPT in init.c just to be consistent */ + if (pmd_val(*pmd)==NULL) { + spt_entry = (pmd - (pmd_t *)(pgdptr->pmd))<< (PAGE_SHIFT+7) | PAGE_OFFSET; + spte = GET_SPTE_VIRT(spt_entry); + pmd_val(*pmd) = spte; + } + return pte_offset(pmd, adjusted_address); + } else return NULL; } @@ -390,11 +432,11 @@ /* FIXME: should test pgdp. this is pointless otherwise */ if ((!pgdp)||(pgd_none(*pgdp))) { printk(KERN_ERR "VAXMM: Bad PGD (%8p, from pmd %8p) in pte_alloc\n",pgdp,pmd_basep); - return NULL; + goto give_segv; } if (pgdp->pmd != (unsigned long)pmd_basep) { printk(KERN_ERR "VAXMM: Mismatched PGD (%8p, has pmd %8lx from pmd %8p) in pte_alloc\n",pgdp,pgdp->pmd,pmd_basep); - return NULL; + goto give_segv; } is_p1=pgdp->segment; @@ -404,14 +446,18 @@ /* make an adjusted address + calculate linear page table entry */ adjusted_address = (((pmd-pmd_basep))<<(PAGE_SHIFT+7))+ (address&~PMD_MASK); + + + /* enforce wsmax memory limits */ if (is_p1){ adjusted_address |= 0x40000000; + if (adjusted_address <= (PAGE_OFFSET-TASK_STKMAX)) goto give_segv; pte_number = (adjusted_address - 0x40000000) >> PAGE_SHIFT; } else { + if (adjusted_address >= (TASK_WSMAX+TASK_MMAPMAX)) goto give_segv; pte_number = (adjusted_address>>PAGE_SHIFT); } - /* FIXME: check against WSMAX */ /* check that the pte we want isnt already allocated */ if (is_p1) { @@ -451,7 +497,7 @@ for (ii=0; ii<npages; ii++) { if (!(pte_page=pte_alloc_one(pmdi))) { printk(KERN_ERR "VAXMM: Unable to expand process page table (pgd=%8p)\n",pgdp); - return NULL; + goto give_segv; } /* remap and clear this page */ @@ -483,6 +529,11 @@ /* we flush tlb anways as we have touched S0 page tables */ flush_tlb_all(); return pte_offset(pmd, adjusted_address); + +give_segv: + printk(KERN_ERR "pte_alloc: sending SIGSEGV to process %p\n",current); + force_sig(SIGSEGV,current); + return NULL; } /* pte_alloc */ @@ -507,11 +558,20 @@ } /* Find an entry in the third-level page table.. */ +#ifdef VAX_MM_PGALLOC_DEBUG +pte_t * pte_offset(pmd_t * dir, unsigned long address) +{ + unsigned long int offset; + offset = (pmd_val(*dir)+(((address>>PAGE_SHIFT)&(PTRS_PER_PTE-1))<<SIZEOF_PTE_LOG2)); + printk(KERN_DEBUG "VAXMM:pte_offset: pmd %8p, address %8lx, pte_offset %8lx\n",dir, address, offset); + return offset; +} +#else pte_t * pte_offset(pmd_t * dir, unsigned long address) { return (pmd_val(*dir)+(((address>>PAGE_SHIFT)&(PTRS_PER_PTE-1))<<SIZEOF_PTE_LOG2)); } - +#endif /* get_pte_kernel_slow. allocate a page of PTEs for the S0 pagetable. * See comments in include/asm/mm/pgalloc.h for get_pte_kernel. */ |
From: Andy P. <at...@us...> - 2001-08-19 10:34:45
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/boot In directory usw-pr-cvs1:/tmp/cvs-serv6214 Modified Files: Makefile Added Files: startup.c Removed Files: tmp_init.c Log Message: Clean up initial boot sequence. Remove vestiges of debugging init sequence --- NEW FILE --- /* First C code - started by head.S */ /* Copyright atp 1998-2001 under the GNU GPL */ #include <asm/rpb.h> #include <asm/mv.h> #include <linux/mm.h> /* stuff that is declared in head.S */ extern unsigned long int phys_start; /* physical address of kernel*/ extern unsigned long int virt_start; /* virtual address of kernel */ extern unsigned long int boot_ap; /* argument pointer */ extern unsigned long int boot_r11; /* rpb pointer */ extern unsigned long int boot_scb; /* scb pointer */ extern unsigned long int iomap_base; /* head.S copies the RPB into this structure */ struct rpb_struct boot_rpb; /* head.S gets the size of the RPB from here. We do it this way because we can't use sizeof() in assembly :-( */ unsigned int rpb_size = sizeof(struct rpb_struct); char *vax_linux_banner="Linux/VAX (lin...@mi...)\n"; extern void start_kernel(void); /* This is a transitionary function. When things are finally sorted * the only tasks this function will perform will relate to the interaction * with VMB and other stuff that needs to go on early before we start_kernel() * like patchable control store, memory bitmap creation on non-ROM based * VAXen. * At present its used for testing the early parts of the kernel startup. * The other main thing it does is load the rpb and scb global variables, * and switch on basic paging. The main paging setup is done later. * * ok ive changed my mind. We turn on MM in the asm before we hit C code * (keeps stacks simpler) just like the i386, with a default 8mb system * page table setup (with a 1:1 mapping of system space. * * Things that are temporary have a habit of becoming permanent. * I've renamed from tmp_start_kernel to vax_start_kernel, as convenient * bit of arch-specific C code before starting the main start_kernel * * atp aug 2001 - This is now permanent, and has been renamed to startup.c */ #define IOMAP_START (PAGE_OFFSET+((iomap_base-swapper_pg_dir[2].br)<<(PAGELET_SHIFT-2))) void vax_start_kernel(void) { /* set the number of 4k pages */ max_pfn = max_hwpfn/8; printk(vax_linux_banner); /* Protect us from interrupt stack overflows */ guard_int_stack(); /* If it is possible to register a console for your machine at this point in the boot sequence, do so in post_vm_init(). Otherwise, implement mv->console_init() which will be called later. */ mv->post_vm_init(); #ifdef __SMP__ static int boot_cpu = 1; /* "current" has been set up, we need to load it now */ if (!boot_cpu) initialize_secondary(); boot_cpu = 0; #endif /* * Interrupts are still disabled. Do necessary setups, then * enable them */ printk("RPB info: l_pfncnt: %08x, .l_vmb_version: %08x .l_badpgs: %08x\n", boot_rpb.l_pfncnt, boot_rpb.l_vmb_version, boot_rpb.l_badpgs); printk("Physical memory: %08x HW pagelets, %08lx pages (%dKB)\n", max_hwpfn, max_pfn, max_hwpfn/2); printk("CPU type: %s, SID: %08x\n", mv->cpu_type_str(), vax_cpu.sid); printk("VM: mapped physical from %x to %x, iomap from %x\n", PAGE_OFFSET, PAGE_OFFSET+(max_hwpfn*512), IOMAP_START); printk("VM: vmalloc from %x to %x\n", VMALLOC_START, VMALLOC_END); printk("VM: ptemap from %x to %x for %d processes\n",TASKPTE_START, TASKPTE_END,TASK_MAXUPRC); printk("calling start_kernel...\n"); start_kernel(); } Index: Makefile =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/boot/Makefile,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- Makefile 2001/03/04 23:44:42 1.4 +++ Makefile 2001/08/19 10:34:42 1.5 @@ -14,6 +14,6 @@ all: head.o libboot.a L_TARGET := libboot.a -obj-y := tmp_init.o lib.o hexdump.o mmstart.o cpu_sel.o +obj-y := startup.o lib.o hexdump.o mmstart.o cpu_sel.o include $(TOPDIR)/Rules.make --- tmp_init.c DELETED --- |
From: Andy P. <at...@us...> - 2001-08-19 10:33:00
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv6028 Modified Files: interrupt.c syscall.c Log Message: place do_signal call in correct place Index: interrupt.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/interrupt.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- interrupt.c 2001/07/31 17:28:26 1.13 +++ interrupt.c 2001/08/19 10:32:57 1.14 @@ -358,7 +358,12 @@ schedule(); goto ret_from_sys_call; } - /* Check for signals here */ + + /* check for pending signals */ + if (current->sigpending != 0) { + /* FIXME: do we need to check the IPL here (i386 does a sti here) */ + do_signal(); + } done: } @@ -633,8 +638,10 @@ struct irqvector *vector; unsigned char *inside_vec; - for (i=0; i<NR_IRQS; i++) + printk("get irq list: \n"); + for (i=0; i<NR_IRQS; i++) { + printk("\t%d: scb free %d\n",i,scb_vec_free(i)); if (!scb_vec_free(i)) { inside_vec = SCB_VECTOR(i); @@ -647,6 +654,7 @@ vector = (struct irqvector *)(inside_vec - offsetof(struct irqvector, inst_jsb)); len += sprintf(buf+len, "%4d: %8d %s\n", vector->vec_num, 0, vector->action.name); + printk("%4d: %8d %s, len %d\n", vector->vec_num, 0, vector->action.name, len); } } return len; Index: syscall.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/syscall.c,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- syscall.c 2001/08/17 20:20:41 1.5 +++ syscall.c 2001/08/19 10:32:58 1.6 @@ -118,19 +118,6 @@ // printk("syscall %d returned %ld (0x%08lx)\n", chmk_arg, regs->r0, regs->r0); - /* now we check for softirqs ready to be run */ - /* This is the equivalent of ENTRY(ret_from_syscall) on other ports */ - if ( (softirq_active(smp_processor_id()) & softirq_mask(smp_processor_id())) !=0 ) do_softirq(); - - /* check for need_reschedule */ - if (current->need_resched !=0) schedule(); - - /* check for pending signals */ - if (current->sigpending != 0) { - /* FIXME: do we need to check the IPL here (i386 does a sti here) */ - do_signal(); - } - return; } |
From: Andy P. <at...@us...> - 2001-08-17 20:36:33
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv21901 Modified Files: process.c Log Message: Signals implementation. Index: process.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/process.c,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- process.c 2001/07/31 17:28:26 1.10 +++ process.c 2001/08/17 20:36:30 1.11 @@ -110,8 +110,8 @@ struct pt_regs *child_regs; void *stack_top; - printk("copy_thread: creating new thread: pid %d, task 0x%08lx, usp 0x%08lx\n", - p->pid, (unsigned long)p, usp); +/* printk("copy_thread: creating new thread: pid %d, task 0x%08lx, usp 0x%08lx\n", + p->pid, (unsigned long)p, usp); */ stack_top = ((union task_union *)p) + 1; @@ -180,8 +180,8 @@ /* In child. At this point SP points to the very top of our kernel stack, so we cannot pop anything off. That means that we can never return from here. */ - printk("kernel_thread: calling thread function at %08lx\n", - (unsigned long)fn); +/* printk("kernel_thread: calling thread function at %08lx\n", + (unsigned long)fn);*/ kernel_thread_exit(fn(arg)); } @@ -193,12 +193,12 @@ newsp = regs->sp; } - printk("sys_clone: calling do_fork(0x%08lx, 0x%08lx, 0x%p)\n", - clone_flags, newsp, regs); +/* printk("sys_clone: calling do_fork(0x%08lx, 0x%08lx, 0x%p)\n", + clone_flags, newsp, regs); */ retval = do_fork(clone_flags, newsp, regs, 0); - printk("sys_clone: do_fork() returned %d\n", retval); +/* printk("sys_clone: do_fork() returned %d\n", retval);*/ return retval; } @@ -250,7 +250,7 @@ void start_thread(struct pt_regs *regs, unsigned long new_pc, unsigned long new_sp) { - printk("starting thread %8lX %8lX %8lX\n", new_pc, new_sp, regs->sp); +/* printk("starting thread %8lX %8lX %8lX\n", new_pc, new_sp, regs->sp);*/ set_fs(USER_DS); regs->pc = new_pc; regs->sp = new_sp; |
From: Andy P. <at...@us...> - 2001-08-17 20:35:18
|
Update of /cvsroot/linux-vax/kernel-2.4/fs/reiserfs In directory usw-pr-cvs1:/tmp/cvs-serv21666 Added Files: .cvsignore Log Message: missing cvs ignore file for new file system --- NEW FILE --- *.a.flags *.o.flags .depend *.lst |
From: Andy P. <at...@us...> - 2001-08-17 20:33:32
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax In directory usw-pr-cvs1:/tmp/cvs-serv21311 Modified Files: signal.h Log Message: Included missing signal - SIGSYS Index: signal.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/signal.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- signal.h 2001/01/17 16:18:52 1.1 +++ signal.h 2001/08/17 20:33:29 1.2 @@ -66,6 +66,7 @@ */ #define SIGPWR 30 #define SIGUNUSED 31 +#define SIGSYS 31 /* These should not be considered constants from userland. */ #define SIGRTMIN 32 |
From: Andy P. <at...@us...> - 2001-08-17 20:20:44
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv18613/kernel Modified Files: syscall.c signal.c Log Message: Signals implementation. First attempt. Index: syscall.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/syscall.c,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- syscall.c 2001/07/31 17:28:26 1.4 +++ syscall.c 2001/08/17 20:20:41 1.5 @@ -95,6 +95,7 @@ by the user. We'll sort this out later... - KPH 2000-10-16 */ + /* atp aug 2001, FIXME: ptrace/strace syscall stuff */ __asm__(" pushl %1 \n subl2 %2,sp \n @@ -115,8 +116,21 @@ "g"(-EFAULT) : "r0","r1","r2","r3","r4","r5" /* clobbers*/ ); -/* printk("syscall %d returned %ld (0x%08lx)\n", chmk_arg, regs->r0, regs->r0);*/ +// printk("syscall %d returned %ld (0x%08lx)\n", chmk_arg, regs->r0, regs->r0); + /* now we check for softirqs ready to be run */ + /* This is the equivalent of ENTRY(ret_from_syscall) on other ports */ + if ( (softirq_active(smp_processor_id()) & softirq_mask(smp_processor_id())) !=0 ) do_softirq(); + + /* check for need_reschedule */ + if (current->need_resched !=0) schedule(); + + /* check for pending signals */ + if (current->sigpending != 0) { + /* FIXME: do we need to check the IPL here (i386 does a sti here) */ + do_signal(); + } + return; } Index: signal.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/signal.c,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- signal.c 2001/07/31 17:28:26 1.3 +++ signal.c 2001/08/17 20:20:41 1.4 @@ -1,14 +1,20 @@ -/* - $Id$ - - This file contains the standard functions that the arch-independent - kernel expects for signal handling - - Copyright, 1998-2001 atp, kenn, airlied. - - atp Jul 2001, signal handling, based on S390/Intel version. - -*/ +/* + * linux/arch/vax/kernel/signal.c + * + * From arch/cris/kernel/signal.c + * + * Based on arch/i386/kernel/signal.c by + * Copyright (C) 1991, 1992 Linus Torvalds + * 1997-11-28 Modified for POSIX.1b signals by Richard Henderson * + * + * Ideas also taken from arch/arm. + * + * Copyright (C) 2000 Axis Communications AB + * + * Authors: Bjorn Wesen (bj...@ax...) + * VAX port at...@pe.... + * See syscall.c for details of the call stack layout etc... + */ #include <linux/sched.h> #include <linux/mm.h> @@ -21,12 +27,20 @@ #include <linux/ptrace.h> #include <linux/unistd.h> #include <linux/stddef.h> + +#include <asm/processor.h> #include <asm/ucontext.h> #include <asm/uaccess.h> +#define DEBUG_SIG 0 + +/* FIXME: Check this & fixup other regs, like r0 */ +#define RESTART_VAX_SYSCALL(regs) { (regs)->pc -= 4; } + + #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -asmlinkage int FASTCALL(do_signal(struct pt_regs *regs, sigset_t *oldset)); +int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs); int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) { @@ -66,8 +80,8 @@ /* * Atomically swap in the new signal mask, and wait for a signal. */ -asmlinkage int -sys_sigsuspend(struct pt_regs * regs,int history0, int history1, old_sigset_t mask) +int +sys_sigsuspend(struct pt_regs *regs, old_sigset_t mask) { sigset_t saveset; @@ -77,18 +91,22 @@ siginitset(¤t->blocked, mask); recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - regs->r2 = -EINTR; + regs->r0 = -EINTR; while (1) { - set_current_state(TASK_INTERRUPTIBLE); + current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(regs, &saveset)) + if (do_signal(0, &saveset, regs)) return -EINTR; } } -asmlinkage int -sys_rt_sigsuspend(struct pt_regs * regs,sigset_t *unewset, size_t sigsetsize) +/* + * atp - it is a little confusing, looking at other ports, as to what the arguments to + * this function are. I'm assuming two args, plus our pushed pt_regs set up by syscall + */ +int +sys_rt_sigsuspend(struct pt_regs *regs,sigset_t *unewset, size_t sigsetsize) { sigset_t saveset, newset; @@ -105,17 +123,17 @@ current->blocked = newset; recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - regs->r2 = -EINTR; + regs->r0 = -EINTR; while (1) { - set_current_state(TASK_INTERRUPTIBLE); + current->state = TASK_INTERRUPTIBLE; schedule(); - if (do_signal(regs, &saveset)) + if (do_signal(0, &saveset, regs)) return -EINTR; } } -asmlinkage int +int sys_sigaction(int sig, const struct old_sigaction *act, struct old_sigaction *oact) { @@ -146,10 +164,12 @@ return ret; } -asmlinkage int -sys_sigaltstack(const stack_t *uss, stack_t *uoss, struct pt_regs *regs) + +int +sys_sigaltstack(const stack_t *uss, stack_t *uoss) { - return do_sigaltstack(uss, uoss, regs->sp); /* is ->sp the right one FIXME: check */ + struct pt_regs *regs = (struct pt_regs *) &uss; + return do_sigaltstack(uss, uoss, regs->sp ); } @@ -158,12 +178,14 @@ */ struct sigframe { + char *pretcode; struct sigcontext sc; unsigned long extramask[_NSIG_WORDS-1]; unsigned char retcode[8]; /* trampoline code */ }; struct rt_sigframe { + char *pretcode; struct siginfo *pinfo; void *puc; struct siginfo info; @@ -171,16 +193,462 @@ unsigned char retcode[8]; /* trampoline code */ }; + +static int +restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) +{ + unsigned int err = 0; + unsigned long old_usp; + + /* restore the regs from &sc->regs (same as sc, since regs is first) + * (sc is already checked for VERIFY_READ since the sigframe was + * checked in sys_sigreturn previously) + */ + + if (__copy_from_user(regs, sc, sizeof(struct pt_regs))) + goto badframe; + + /* FIXME: check user mode flag in restored regs PSW */ + + /* restore the old USP as it was before we stacked the sc etc. + * (we cannot just pop the sigcontext since we aligned the sp and + * stuff after pushing it) + */ + + /* FIXME: check process stack */ + + /* TODO: the other ports use regs->orig_XX to disable syscall checks + * after this completes, but we don't use that mechanism. maybe we can + * use it now ? + */ + + return err; + +badframe: + return 1; +} + +asmlinkage int sys_sigreturn(struct pt_regs *regs) +{ + struct sigframe *frame = (struct sigframe *)(regs->sp); + sigset_t set; + + /* + * Since we stacked the signal on a dword boundary, + * then frame should be dword aligned here. If it's + * not, then the user is trying to mess with us. + */ + if (((long)frame) & 3) + goto badframe; + + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__get_user(set.sig[0], &frame->sc.oldmask) + || (_NSIG_WORDS > 1 + && __copy_from_user(&set.sig[1], &frame->extramask, + sizeof(frame->extramask)))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sigmask_lock); + current->blocked = set; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + if (restore_sigcontext(regs, &frame->sc)) + goto badframe; + + /* TODO: SIGTRAP when single-stepping as in arm ? */ + + return regs->r0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) +{ + struct rt_sigframe *frame = (struct rt_sigframe *)(regs->sp); + sigset_t set; + stack_t st; + + /* + * Since we stacked the signal on a dword boundary, + * then frame should be dword aligned here. If it's + * not, then the user is trying to mess with us. + */ + if (((long)frame) & 3) + goto badframe; + + if (verify_area(VERIFY_READ, frame, sizeof(*frame))) + goto badframe; + if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) + goto badframe; + + sigdelsetmask(&set, ~_BLOCKABLE); + spin_lock_irq(¤t->sigmask_lock); + current->blocked = set; + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + + if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) + goto badframe; + + if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st))) + goto badframe; + /* It is more difficult to avoid calling this function than to + call it and ignore errors. */ + do_sigaltstack(&st, NULL, (regs->sp)); + + return regs->r0; + +badframe: + force_sig(SIGSEGV, current); + return 0; +} + +/* + * Set up a signal frame. + */ + +static int +setup_sigcontext(struct sigcontext *sc, struct pt_regs *regs, unsigned long mask) +{ + int err = 0; + + /* copy the regs. they are first in sc so we can use sc directly */ + + err |= __copy_to_user(sc, regs, sizeof(struct pt_regs)); + + /* then some other stuff */ + + err |= __put_user(mask, &sc->oldmask); + + return err; +} + +/* figure out where we want to put the new signal frame - usually on the stack */ -int sys_sigreturn(void) +static inline void * +get_sigframe(struct k_sigaction *ka, struct pt_regs * regs, size_t frame_size) { - return -ENOSYS; + unsigned long sp = regs->sp; + + /* This is the X/Open sanctioned signal stack switching. */ + if (ka->sa.sa_flags & SA_ONSTACK) { + if (! on_sig_stack(sp)) + sp = current->sas_ss_sp + current->sas_ss_size; + } + + /* make sure the frame is dword-aligned */ + + sp &= ~3; + + return (void *)(sp - frame_size); } + +/* grab and setup a signal frame. + * + * basically we stack a lot of state info, and arrange for the + * user-mode program to return to the kernel using either a + * trampoline which performs the syscall sigreturn, or a provided + * user-mode trampoline. + */ -int sys_rt_sigreturn(void) +static void setup_frame(int sig, struct k_sigaction *ka, + sigset_t *set, struct pt_regs * regs) { - return -ENOSYS; + struct sigframe *frame; + unsigned long return_ip; + int err = 0; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto give_sigsegv; + + err |= setup_sigcontext(&frame->sc, regs, set->sig[0]); + if (err) + goto give_sigsegv; + + if (_NSIG_WORDS > 1) { + err |= __copy_to_user(frame->extramask, &set->sig[1], + sizeof(frame->extramask)); + } + if (err) + goto give_sigsegv; + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + if (ka->sa.sa_flags & SA_RESTORER) { + return_ip = (unsigned long)ka->sa.sa_restorer; + } else { + /* trampoline - the desired return ip is the retcode itself */ + return_ip = (unsigned long)&frame->retcode; + /* This is chmk __NR_sigreturn; */ + /* TODO: check byteorder */ + err |= __put_user(0xbc8f, (short *)(frame->retcode+0)); + err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2)); + } + + err |= __put_user(return_ip, &frame->pretcode); + + if (err) + goto give_sigsegv; + + /* Set up registers for signal handler */ + + regs->pc = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */ + regs->sp = frame; + + return; + +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); } +static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, + sigset_t *set, struct pt_regs * regs) +{ + struct rt_sigframe *frame; + unsigned long return_ip; + int err = 0; + + frame = get_sigframe(ka, regs, sizeof(*frame)); + + if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) + goto give_sigsegv; + + err |= __put_user(&frame->info, &frame->pinfo); + err |= __put_user(&frame->uc, &frame->puc); + err |= copy_siginfo_to_user(&frame->info, info); + if (err) + goto give_sigsegv; + + /* Clear all the bits of the ucontext we don't use. */ + err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); + + err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]); + + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + + if (err) + goto give_sigsegv; + + /* Set up to return from userspace. If provided, use a stub + already in userspace. */ + if (ka->sa.sa_flags & SA_RESTORER) { + return_ip = (unsigned long)ka->sa.sa_restorer; + } else { + /* trampoline - the desired return ip is the retcode itself */ + return_ip = (unsigned long)&frame->retcode; + /* TODO: check byteorder */ + err |= __put_user(0xbc8f, (short *)(frame->retcode+0)); + err |= __put_user(__NR_sigreturn, (short *)(frame->retcode+2)); + } + + err |= __put_user(return_ip, &frame->pretcode); + if (err) + goto give_sigsegv; + + /* TODO what is the current->exec_domain stuff and invmap ? */ + + /* Set up registers for signal handler */ + + regs->pc = (unsigned long) ka->sa.sa_handler; /* what we enter NOW */ + regs->sp = frame; /* what we enter LATER */ + + return; +give_sigsegv: + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); +} + +/* + * OK, we're invoking a handler + */ +static inline void +handle_signal(int canrestart, unsigned long sig, struct k_sigaction *ka, + siginfo_t *info, sigset_t *oldset, struct pt_regs * regs) +{ + /* Are we from a system call? */ + if (canrestart) { + /* If so, check system call restarting.. */ + switch (regs->r0) { + case -ERESTARTNOHAND: + /* ERESTARTNOHAND means that the syscall should only be + restarted if there was no handler for the signal, and since + we only get here if there is a handler, we dont restart */ + regs->r0 = -EINTR; + break; + + case -ERESTARTSYS: + /* ERESTARTSYS means to restart the syscall if there is no + handler or the handler was registered with SA_RESTART */ + if (!(ka->sa.sa_flags & SA_RESTART)) { + regs->r0 = -EINTR; + break; + } + /* fallthrough */ + case -ERESTARTNOINTR: + /* ERESTARTNOINTR means that the syscall should be called again + after the signal handler returns. */ + RESTART_VAX_SYSCALL(regs); + } + } + + /* Set up the stack frame */ + if (ka->sa.sa_flags & SA_SIGINFO) + setup_rt_frame(sig, ka, info, oldset, regs); + else + setup_frame(sig, ka, oldset, regs); + + if (ka->sa.sa_flags & SA_ONESHOT) + ka->sa.sa_handler = SIG_DFL; + + if (!(ka->sa.sa_flags & SA_NODEFER)) { + spin_lock_irq(¤t->sigmask_lock); + sigorsets(¤t->blocked,¤t->blocked,&ka->sa.sa_mask); + sigaddset(¤t->blocked,sig); + recalc_sigpending(current); + spin_unlock_irq(¤t->sigmask_lock); + } +} + +/* + * Note that 'init' is a special process: it doesn't get signals it doesn't + * want to handle. Thus you cannot kill init even with a SIGKILL even by + * mistake. + */ +int do_signal(int canrestart, sigset_t *oldset, struct pt_regs *regs) +{ + siginfo_t info; + struct k_sigaction *ka; + + /* + * We want the common case to go fast, which + * is why we may in certain cases get here from + * kernel mode. Just return without doing anything + * if so. + */ + if (!user_mode(regs)) + return 1; + + if (!oldset) + oldset = ¤t->blocked; + + for (;;) { + unsigned long signr; + + spin_lock_irq(¤t->sigmask_lock); + signr = dequeue_signal(¤t->blocked, &info); + spin_unlock_irq(¤t->sigmask_lock); + + if (!signr) + break; + + if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { + /* Let the debugger run. */ + current->exit_code = signr; + current->state = TASK_STOPPED; + notify_parent(current, SIGCHLD); + schedule(); + + /* We're back. Did the debugger cancel the sig? */ + if (!(signr = current->exit_code)) + continue; + current->exit_code = 0; + + /* The debugger continued. Ignore SIGSTOP. */ + if (signr == SIGSTOP) + continue; + + /* Update the siginfo structure. Is this good? */ + if (signr != info.si_signo) { + info.si_signo = signr; + info.si_errno = 0; + info.si_code = SI_USER; + info.si_pid = current->p_pptr->pid; + info.si_uid = current->p_pptr->uid; + } + + /* If the (new) signal is now blocked, requeue it. */ + if (sigismember(¤t->blocked, signr)) { + send_sig_info(signr, &info, current); + continue; + } + } + + ka = ¤t->sig->action[signr-1]; + if (ka->sa.sa_handler == SIG_IGN) { + if (signr != SIGCHLD) + continue; + /* Check for SIGCHLD: it's special. */ + while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) + /* nothing */; + continue; + } + + if (ka->sa.sa_handler == SIG_DFL) { + int exit_code = signr; + + /* Init gets no signals it doesn't want. */ + if (current->pid == 1) + continue; + + switch (signr) { + case SIGCONT: case SIGCHLD: case SIGWINCH: + continue; + + case SIGTSTP: case SIGTTIN: case SIGTTOU: + if (is_orphaned_pgrp(current->pgrp)) + continue; + /* FALLTHRU */ + + case SIGSTOP: + current->state = TASK_STOPPED; + current->exit_code = signr; + if (!(current->p_pptr->sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) + notify_parent(current, SIGCHLD); + schedule(); + continue; + + case SIGQUIT: case SIGILL: case SIGTRAP: + case SIGABRT: case SIGFPE: case SIGSEGV: + case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: + if (do_coredump(signr, regs)) + exit_code |= 0x80; + /* FALLTHRU */ + + default: + lock_kernel(); + sigaddset(¤t->pending.signal, signr); + recalc_sigpending(current); + current->flags |= PF_SIGNALED; + do_exit(exit_code); + /* NOTREACHED */ + } + } + + /* Whee! Actually deliver the signal. */ + handle_signal(canrestart, signr, ka, &info, oldset, regs); + return 1; + } + + /* Did we come from a system call? */ + if (canrestart) { + /* Restart the system call - no handlers present */ + if (regs->r0 == -ERESTARTNOHAND || + regs->r0 == -ERESTARTSYS || + regs->r0 == -ERESTARTNOINTR) { + RESTART_VAX_SYSCALL(regs); + } + } + return 0; +} |
From: Andy P. <at...@us...> - 2001-08-17 20:20:44
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv18613/mm Modified Files: fault.c Log Message: Signals implementation. First attempt. Index: fault.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/mm/fault.c,v retrieving revision 1.7 retrieving revision 1.8 diff -u -r1.7 -r1.8 --- fault.c 2001/07/31 17:28:26 1.7 +++ fault.c 2001/08/17 20:20:41 1.8 @@ -130,7 +130,8 @@ printk("do_page_fault: sending SIGSEGV\n"); force_sig(SIGSEGV, current); /* signals arent implemented yet */ - machine_halt(); + /* They are now atp aug 17 2001 */ +// machine_halt(); return; } |
From: Dave A. <ai...@us...> - 2001-08-15 22:55:17
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv12396 Modified Files: entry.S Log Message: DA: oops .. wrong calll.. I'm, redoing the whole lot of entry.S now.. missing some stuff .. other stuff to 16/32 bit stuff Index: entry.S =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/entry.S,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- entry.S 2001/08/15 22:23:32 1.6 +++ entry.S 2001/08/15 22:55:13 1.7 @@ -304,7 +304,7 @@ .long sys_geteuid .long sys_getegid /* 50 */ .long sys_acct - .long sys_umount /* recycled never used phys() */ + .long sys_oldumount /* recycled never used phys() */ .long sys_ni_syscall /* old lock syscall holder */ .long sys_ioctl .long sys_fcntl /* 55 */ |
From: Dave A. <ai...@us...> - 2001-08-15 22:24:29
|
Update of /cvsroot/linux-vax/kernel-2.4/drivers/net In directory usw-pr-cvs1:/tmp/cvs-serv5261/drivers/net Modified Files: vaxlance.c Log Message: DA: add some missing CRs Index: vaxlance.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/net/vaxlance.c,v retrieving revision 1.14 retrieving revision 1.15 diff -u -r1.14 -r1.15 --- vaxlance.c 2001/08/14 21:25:43 1.14 +++ vaxlance.c 2001/08/15 22:24:27 1.15 @@ -1077,11 +1077,11 @@ #else dev->irq=0x94; - printk("Using LANCE interrupt vector %d", dev->irq); + printk("Using LANCE interrupt vector %d\n", dev->irq); #endif /* tmp atp*/ dev->irq=0x94; - printk("Using LANCE interrupt vector %d", dev->irq); + printk("Using LANCE interrupt vector %d\n", dev->irq); dev->open = &lance_open; dev->stop = &lance_close; |
From: Dave A. <ai...@us...> - 2001-08-15 22:23:37
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel In directory usw-pr-cvs1:/tmp/cvs-serv4962/arch/vax/kernel Modified Files: entry.S Log Message: DA: umount is implemented on my box :-).... needed to get busybox to umount ... Index: entry.S =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/kernel/entry.S,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- entry.S 2001/06/26 18:59:00 1.5 +++ entry.S 2001/08/15 22:23:32 1.6 @@ -274,7 +274,7 @@ .long sys_lseek .long sys_getpid /* 20 */ .long sys_mount - .long sys_ni_syscall /* old umount syscall holder */ + .long sys_umount /* old umount syscall holder */ .long sys_setuid .long sys_getuid .long sys_stime /* 25 */ |
From: Dave A. <ai...@us...> - 2001-08-14 21:25:47
|
Update of /cvsroot/linux-vax/kernel-2.4/arch/vax In directory usw-pr-cvs1:/tmp/cvs-serv16198/arch/vax Modified Files: config.in Log Message: DA: hackage for 4000/60 testing see what happens .. will be removed later Index: config.in =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/arch/vax/config.in,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- config.in 2001/06/16 19:42:11 1.5 +++ config.in 2001/08/14 21:25:43 1.6 @@ -74,6 +74,9 @@ bool 'Support for Unibus' CONFIG_UNIBUS bool 'Support for VAXBI' CONFIG_VAXBI bool 'Support for Vax Station BUS (??)' CONFIG_VSBUS + if [ "$CONFIG_VSBUS" != "n" ]; then + bool 'Hardcode 4000/60 (temporary for now - DA)' CONFIG_VAX_4000HC + fi endmenu mainmenu_option next_comment |
From: Dave A. <ai...@us...> - 2001-08-14 21:25:46
|
Update of /cvsroot/linux-vax/kernel-2.4/drivers/net In directory usw-pr-cvs1:/tmp/cvs-serv16198/drivers/net Modified Files: vaxlance.c Log Message: DA: hackage for 4000/60 testing see what happens .. will be removed later Index: vaxlance.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/net/vaxlance.c,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- vaxlance.c 2001/07/31 17:47:26 1.13 +++ vaxlance.c 2001/08/14 21:25:43 1.14 @@ -1016,6 +1016,7 @@ // lp->vsbus_int=5; #ifdef CONFIG_VSBUS +#ifndef CONFIG_VAX_4000HC { int num, irq; autoirq_setup(0); @@ -1029,10 +1030,14 @@ if (num) lp->vsbus_int=num; } +#else + lp->vsbus_int=1; #endif + +#endif #ifdef VAX_LANCE_AUTOPROBE_IRQ - +#ifndef CONFIG_VAX_4000HC printk("Autoprobing LANCE interrupt vector..."); @@ -1058,6 +1063,9 @@ /* maybe we should stop the LANCE here? */ vsbus_clear_int(lp->vsbus_int); +#else + dev->irq=254; +#endif if (dev->irq) printk(" probed IRQ %d, vsbus %d\n", dev->irq, lp->vsbus_int); else @@ -1066,6 +1074,7 @@ printk(" failed to detect IRQ line - assuming 0x94.\n"); } /* Fill the dev fields */ + #else dev->irq=0x94; printk("Using LANCE interrupt vector %d", dev->irq); |
From: Dave A. <ai...@us...> - 2001-08-14 21:25:46
|
Update of /cvsroot/linux-vax/kernel-2.4/drivers/char In directory usw-pr-cvs1:/tmp/cvs-serv16198/drivers/char Modified Files: dz.c Log Message: DA: hackage for 4000/60 testing see what happens .. will be removed later Index: dz.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/char/dz.c,v retrieving revision 1.6 retrieving revision 1.7 diff -u -r1.6 -r1.7 --- dz.c 2001/06/17 11:43:44 1.6 +++ dz.c 2001/08/14 21:25:43 1.7 @@ -1455,6 +1455,7 @@ it is unwise. */ restore_flags(flags); #if CONFIG_VAX +#ifndef CONFIG_VAX_4000HC { short i; unsigned char num; @@ -1489,7 +1490,15 @@ vsbus_disable_int(num); irq=autoirq_report(100); } +#else + dz_vsbus_tx_int=4; + dz_vsbus_rx_int=5; + irq=149; + +#endif printk("dz.c: using irq rx %d, irq tx %d\n", irq-1, irq); + + if (request_irq (irq, dz_interrupt_tx, SA_INTERRUPT, "DZ", lines[0])) panic ("Unable to register DZ interrupt\n"); if (request_irq (irq-1, dz_interrupt_rx, SA_INTERRUPT, "DZ", lines[0])) |
From: Dave A. <ai...@us...> - 2001-08-06 18:41:10
|
Update of /cvsroot/linux-vax/tools/src/ld/emulparams In directory usw-pr-cvs1:/tmp/cvs-serv5176 Modified Files: elf_vax.sh Log Message: DA: changes for compiling user space programs Index: elf_vax.sh =================================================================== RCS file: /cvsroot/linux-vax/tools/src/ld/emulparams/elf_vax.sh,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- elf_vax.sh 2000/07/26 23:17:06 1.1 +++ elf_vax.sh 2001/08/06 18:41:07 1.2 @@ -1,8 +1,8 @@ SCRIPT_NAME=elf OUTPUT_FORMAT="elf32-vax" -TEXT_START_ADDR=0x08048000 +TEXT_START_ADDR=0x1000 MAXPAGESIZE=0x1000 -NONPAGED_TEXT_START_ADDR=0x08048000 +NONPAGED_TEXT_START_ADDR=0x1000 ARCH=vax MACHINE= NOP=0x0101 |
From: Andy P. <at...@us...> - 2001-07-31 17:54:08
|
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax In directory usw-pr-cvs1:/tmp/cvs-serv6688 Removed Files: old.bitops.h old.init.h old.spinlock.h old.system.h Log Message: trim old files --- old.bitops.h DELETED --- --- old.init.h DELETED --- --- old.spinlock.h DELETED --- --- old.system.h DELETED --- |
From: Andy P. <at...@us...> - 2001-07-31 17:50:29
|
Update of /cvsroot/linux-vax/kernel-2.4 In directory usw-pr-cvs1:/tmp/cvs-serv5817 Modified Files: Makefile Log Message: fixes. Index: Makefile =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/Makefile,v retrieving revision 1.11 retrieving revision 1.12 diff -u -r1.11 -r1.12 --- Makefile 2001/03/07 02:08:40 1.11 +++ Makefile 2001/07/31 17:50:26 1.12 @@ -40,6 +40,7 @@ MODFLAGS = -DMODULE CFLAGS_KERNEL = PERL = perl +MAKE = make -j3 export VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION KERNELRELEASE ARCH \ CONFIG_SHELL TOPDIR HPATH HOSTCC HOSTCFLAGS CROSS_COMPILE AS LD CC \ |
From: Andy P. <at...@us...> - 2001-07-31 17:47:29
|
Update of /cvsroot/linux-vax/kernel-2.4/drivers/net In directory usw-pr-cvs1:/tmp/cvs-serv5014 Modified Files: vaxlance.c Log Message: Made the diagmem thing a bit cleaner calls to a routine in arch/vax/kernel/cpu_ka43.c now Index: vaxlance.c =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/drivers/net/vaxlance.c,v retrieving revision 1.12 retrieving revision 1.13 diff -u -r1.12 -r1.13 --- vaxlance.c 2001/06/17 11:43:45 1.12 +++ vaxlance.c 2001/07/31 17:47:26 1.13 @@ -953,26 +953,9 @@ */ - /* KA43 only. - * - * The KA43 seems to be nicely fscked up... All physical memory - * is accessible from 0x00000000 up (as normal) and also from - * 0x28000000 (KA43_DIAGMEM) in IO space. In order to reliably - * share memory with the LANCE, we _must_ read and write to this - * shared memory via the DIAGMEM region. Maybe this bypasses - * caches or something... If you don't do this you get evil - * "memory read parity error" machine checks. - * - */ - - /* You MUST remember to clear the DIAGMEM bits in these PTEs - before giving the pages back to free_pages() */ - - pte_t *p = GET_SPTE_VIRT(dev->mem_start); - for (i=0; i<(65536>>PAGE_SHIFT); i++, p++) { - set_pte(p, __pte(pte_val(*p) | (KA43_DIAGMEM >> PAGELET_SHIFT))); - __flush_tlb_one(dev->mem_start + i * PAGE_SIZE); - } + /* KA43 only. */ + ka43_diagmem_remap(dev->mem_start, 65536); + } @@ -1087,7 +1070,11 @@ dev->irq=0x94; printk("Using LANCE interrupt vector %d", dev->irq); #endif - dev->open = &lance_open; + /* tmp atp*/ + dev->irq=0x94; + printk("Using LANCE interrupt vector %d", dev->irq); + + dev->open = &lance_open; dev->stop = &lance_close; dev->hard_start_xmit = &lance_start_xmit; dev->tx_timeout = &lance_tx_timeout; |
Update of /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm In directory usw-pr-cvs1:/tmp/cvs-serv1125/mm Modified Files: mmu_context.h pagelet.h pagelet_pgd.h pagelet_pmd.h pagelet_pte.h pgalloc.h pgtable.h tlb.h Added Files: task.h Log Message: New mm layer + start of signal handling + misc fixes --- NEW FILE --- #ifndef __VAX_MM_TASK_H #define __VAX_MM_TASK_H /* task.h - task memory map defines */ /* atp July 2001. */ /* These are all used to size the relevant structures in the system * page table, in paging_init (arch/vax/mm/init.c) */ /* currently allocate 32mb of virtual memory */ /* These defines cover the process memory map, and are in bytes */ /* Please remember to make them a multiple of PAGE_SIZE, or its going to * get wierd here */ /* TASK_WSMAX is the max virtual address space in P0 */ /* TASK_WSMAX must not be larger than 768MB. In the unlikely event that * you really want to allocate that much to a process, change PGD_SPECIAL below */ #define TASK_WSMAX (40*1024*1024) /* TASK_STKMAX is the max space for the stack in P1 */ /* Like WSMAX above, the upper limit for this is set by PGD_SPECIAL below. If this * is above 256MB change PGD_SPECIAL */ #define TASK_STKMAX (8*1024*1024) /* TASK_MMAPMAX is the max space in P0 for the mmap() function , contiguous with TASK_WSMAX */ #define TASK_MMAPMAX (8*1024*1024) /* TASK_MAXUPRC is the maximum number of user processes on the system * Think of this like balsetcnt on VMS. * -- this should also set/be set by the linux max task variable */ #define TASK_MAXUPRC (32) /* * This decides where the kernel will search for a free chunk of vm * space during mmap's. */ #define TASK_UNMAPPED_BASE TASK_WSMAX /* calculations based on the above for the SPT */ /* NPTE_TASK = the number of HWPTE's needed to map a process */ #define N_HWPTE_TASK_P0 ((TASK_WSMAX+TASK_MMAPMAX)>>PAGELET_SHIFT) #define N_HWPTE_TASK_P1 ((TASK_STKMAX)>>PAGELET_SHIFT) /* There are 4 4096 byte pages in the pmd. = 4x1024 hwptes. */ #define N_HWPTE_TASK_PMD ((4*1024)) #define N_HWPTE_TASK (N_HWPTE_TASK_P0+N_HWPTE_TASK_P1+N_HWPTE_TASK_PMD) /* The alignment we want - at present double page for pte_alloc/offset to work ok */ #define PTE_TASK_MASK (~(8191)) #define PTE_TASK_ALIGN(x) (((x)+8191)&PTE_TASK_MASK) /* size in bytes of an aligned task pte region */ #define PTE_TASK_SLOTSIZE PTE_TASK_ALIGN(N_HWPTE_TASK<<2) /* The number of pagelets, or SPTEs needed to hold this number of HWPTEs */ #define SPTE_MAX_TASKPTE ((N_HWPTE_TASK>>(PAGELET_SHIFT-2))+1) /* The offsets into page table area from the start of this slot, in bytes */ #define P0PTE_OFFSET (N_HWPTE_TASK_PMD<<2) #define P1PTE_OFFSET ((N_HWPTE_TASK_P0+N_HWPTE_TASK_PMD)<<2) #define P0PMD_OFFSET (0) #define P1PMD_OFFSET (PAGE_SIZE*2) /* * This is a special index into the pmd. This stores a back pointer to the * pgd in the pmd. The default value of 1536 allows 768 MB for WSMAX and 256 * MB for stack. If you want to change that allocation, bear in mind that you * have to trade WSMAX for STKMAX. Unless I think of a cleverer way of doing this. */ #define PGD_SPECIAL 1536 /* * User space process size: 2GB (default). * This is a bit bogus - a linux thing. */ #define TASK_SIZE (PAGE_OFFSET) #endif /* __VAX_MM_TASK_H */ Index: mmu_context.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/mmu_context.h,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- mmu_context.h 2001/06/09 18:00:25 1.3 +++ mmu_context.h 2001/07/31 17:33:26 1.4 @@ -1,8 +1,6 @@ -/* Copyright (C) May 2001 - Dave Airlie - Vax project - ai...@li... - derived I'm sure from somewhere ... */ - #ifndef _ASM_VAX_MMU_CONTEXT_H #define _ASM_VAX_MMU_CONTEXT_H +/* atp Jan 2001 */ #include <asm/mm/tlb.h> @@ -12,6 +10,26 @@ #define destroy_context(mm) flush_tlb_mm(mm) +static inline void set_vaxmm_regs_p0(pgd_t *pgdp) +{ + __mtpr(pgdp->br, PR_P0BR); + __mtpr( (pgdp->lr * 8), PR_P0LR); +} + +static inline void set_vaxmm_regs_p1(pgd_t *pgdp) +{ + __mtpr(pgdp->br, PR_P1BR); + __mtpr( (pgdp->lr * 8), PR_P1LR); +} + +static inline void set_vaxmm_regs(pgd_t *pgdp) +{ + __mtpr((pgdp[0]).br, PR_P0BR); + __mtpr( ((pgdp[0]).lr * 8), PR_P0LR); + __mtpr((pgdp[1]).br, PR_P1BR); + __mtpr( ((pgdp[1]).lr * 8), PR_P1LR); +} + static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) { @@ -30,15 +48,12 @@ clear_bit(cpu, &prev->cpu_vm_mask); tsk->thread.pcb.p0br = (next->pgd[0]).br; - tsk->thread.pcb.p0lr = (next->pgd[0]).lr * 8 | 0x04000000; + tsk->thread.pcb.p0lr = (next->pgd[0]).lr * 8 /*| 0x04000000*/; tsk->thread.pcb.p1br = (next->pgd[1]).br; tsk->thread.pcb.p1lr = (next->pgd[1]).lr * 8; - __mtpr(next->pgd[0].br, PR_P0BR); - __mtpr((next->pgd[0].lr * 8), PR_P0LR); - __mtpr(next->pgd[1].br, PR_P1BR); - __mtpr((next->pgd[1].lr * 8), PR_P1LR); - + set_vaxmm_regs(next->pgd); + flush_tlb_all(); } set_bit(cpu, &next->cpu_vm_mask); Index: pagelet.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pagelet.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- pagelet.h 2001/02/15 16:50:54 1.2 +++ pagelet.h 2001/07/31 17:33:26 1.3 @@ -73,11 +73,18 @@ struct vax_pgd_descriptor { unsigned long br; unsigned long lr; + unsigned long pmd; /* first four pages of the task PTE slot are the pmds + * There are two pmd's one for p0 and one for p1 */ + unsigned long pmd2; /* This is just a place holder, as we pretend that + * our pmds hold 2048 entries and are 2 pages long */ + unsigned long slot; /* the base address of this slot */ + unsigned long segment; /* The segment index - used in pgd_clear */ }; /* pgd_t definitions */ typedef struct vax_pgd_descriptor pgd_t; -#define pgd_val(x) ((x).br) +/* the .pmd is not a typo */ +#define pgd_val(x) ((x).pmd) #define __pgd(x) ((pgd_t) { (x) } ) /* definition of pmd_t */ @@ -90,6 +97,11 @@ #define pte_val(x) ((x).pte) #define __pte(x) ((pte_t) { (x) } ) + +/* hwpte_t */ +typedef struct { unsigned long hwpte; } hwpte_t; +#define hwpte_val(x) ((x).hwpte) +#define __hwpte(x) ((hwpte_t) { (x) } ) /* and pgprot_t */ typedef struct { unsigned long pgprot; } pgprot_t; Index: pagelet_pgd.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pagelet_pgd.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- pagelet_pgd.h 2001/02/15 01:17:23 1.1 +++ pagelet_pgd.h 2001/07/31 17:33:26 1.2 @@ -45,10 +45,11 @@ * into the pgd entry) * All the actual stuff is done by the pmd_xxx functions */ -extern inline int pgd_none(pgd_t pgd) { return 0; } -extern inline int pgd_bad(pgd_t pgd) { return 0; } -extern inline int pgd_present(pgd_t pgd) { return 1; } -extern inline void pgd_clear(pgd_t * pgdp) { } +extern inline int pgd_none(pgd_t pgd) { return !(pgd).pmd; } +extern inline int pgd_bad(pgd_t pgd) { return !(pgd).br; } +extern inline int pgd_present(pgd_t pgd) { return ((pgd).pmd != 0); } + +extern void pgd_clear(pgd_t * pgdp); /* to set the page-dir (p0br/p0lr) (p1br/p1lr) see arch/vax/mm/pgtable.c */ extern void set_page_dir(struct task_struct *task, pgd_t *pgdir); Index: pagelet_pmd.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pagelet_pmd.h,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- pagelet_pmd.h 2001/06/17 12:34:05 1.2 +++ pagelet_pmd.h 2001/07/31 17:33:26 1.3 @@ -1,61 +1,65 @@ /* * pagelet_pmd.h * - * Defines the page mid level directory in our fake 2 level paging scheme. - * As for all the 2 level schemes, this is folded away by the compiler. + * Defines the page mid level directory in our fake 3 level paging scheme. * * Copyright atp Jan 2001. + * atp Jul 2001. Go to a fake 3 level. */ -/* PMD_SHIFT determines the size of the area a second-level page table can map */ -/* 128 * 512. 128 ptes/page */ -#define PMD_SHIFT 30 +/* PMD_SHIFT determines the size of the area a second-level page table entry can map */ +/* 1 page of ptes maps 128x4096 bytes = 512kb. + * Each "pmd" here is infact a 2 page = 8kb region at the start of the + * process page table region. It makes the accounting a lot easier. + */ +#define PMD_SHIFT 19 #define PMD_SIZE (1UL << PMD_SHIFT) #define PMD_MASK (~(PMD_SIZE-1)) /* * entries per page directory level: the VAX is single level, so * we don't really have any PMD directory physically, or real pgd for - * that matter. + * that matter. Its just an 8kb region. */ -#define PTRS_PER_PMD 1 +#define PTRS_PER_PMD 2048 #define pmd_ERROR(e) \ printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) /* pmd_xxx functions */ -/* These are really operating on the pgd_t */ -/* These are just testing the br in each pgd_t for the presence/absence of info */ - -/* set_pmd: for the moment, I'm not going to use this. Each pgd_t in the - * pgd should be set by hand at process initialisation. It doesnt need to - * ever change, except for the length register, which is handled in pte_alloc */ -#define set_pmd(pmdptr, pmdval) +/* These are really operating on the first two pages of a balance slot */ +/* + * we dont want linux mucking about with our pmd pages. It will get it + * wrong. pmd_alloc and pmd_free do the business there. + */ +#define set_pmd(pmdptr, pmdval) /* Fixme:, check the length as well as the base register. */ -extern inline int pmd_none(pmd_t pmd) { return (pmd_val(pmd) == 0); } +extern inline int pmd_none(pmd_t pmd) +{ + if (pmd_val(pmd) & 0x1) return 1; + return (pmd_val(pmd) == 0); +} extern inline int pmd_bad(pmd_t pmd) { return (pmd_val(pmd) == 0); } extern inline int pmd_present(pmd_t pmd) { return (pmd_val(pmd) != 0); } -/* This is just zeroing out the base and length registers */ -/* FIXME: or validate code - I removed the zero'ing of the pmd, - pmd are parts of pgds, and if we clear the br/lr of the P0 pmd, - the zeroth member of pgd, we lose the vmalloc address so can't - do vfree. - D.A. June 2001 -*/ -extern inline void pmd_clear(pmd_t * pmdp) { - /* pmd_val(pmdp[0]) = 0; - pmd_val(pmdp[1]) = 0;*/ - } +/* clear the pmd entry */ +extern inline void pmd_clear(pmd_t * pmdp) { pmd_val(*pmdp) = 0; } - /* Find an entry in the second-level page table.. */ +#define pmd_index(address) ((address >> PMD_SHIFT) & (PTRS_PER_PMD-1)) + + extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) { - return (pmd_t *) dir; + pmd_t *ptr; + ptr = (pmd_t *)pmd_val(*dir) + pmd_index(address); + /* locate the pmd entry according to address */ +// printk("pmd_offset: pgd %8p, pmd_val %8lx, address %8lx, index %8lx, offset %8p\n",dir,pmd_val(*dir),address,pmd_index(address),ptr); + return ptr; } Index: pagelet_pte.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pagelet_pte.h,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- pagelet_pte.h 2001/06/16 14:26:36 1.5 +++ pagelet_pte.h 2001/07/31 17:33:26 1.6 @@ -33,17 +33,17 @@ * Note that the first hwpte is the one that linux sees. * The first hwpte is used for all tests except * the dirty test, which has to be applied to all */ -typedef unsigned long hwpte_t; +/*typedef unsigned long hwpte_t;*/ typedef struct pagelet_pagecluster { - hwpte_t pte; - hwpte_t pte1; - hwpte_t pte2; - hwpte_t pte3; - hwpte_t pte4; - hwpte_t pte5; - hwpte_t pte6; - hwpte_t pte7; + unsigned long pte; + unsigned long pte1; + unsigned long pte2; + unsigned long pte3; + unsigned long pte4; + unsigned long pte5; + unsigned long pte6; + unsigned long pte7; } pagecluster_t; /* each ptr is 32 bytes in size */ @@ -70,7 +70,7 @@ /* to find an entry in a page-table */ #define PAGE_PTR(address) \ -((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTE_LOG2)&PTE_MASK&~PAGE_MASK) +((unsigned long)(((address)>>PAGE_SHIFT)<<SIZEOF_PTE_LOG2)&PTE_MASK&~PAGE_MASK) /* Certain architectures need to do special things when PTEs @@ -101,6 +101,11 @@ ptep->pte6 = pte_val(pte)+6; ptep->pte7 = pte_val(pte)+7; } + +static inline void print_pte(pte_t *ptep) +{ + printk(KERN_DEBUG "%8p: %8lx %8lx %8lx %8lx %8lx %8lx %8lx %8lx\n", ptep, ptep->pte,ptep->pte1,ptep->pte2,ptep->pte3,ptep->pte4,ptep->pte5,ptep->pte6,ptep->pte7); +} /* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. @@ -112,21 +117,24 @@ * * See asm-i386/pgtable-3level.h for background. */ -/* D.A. May 2001 - FIXME: this needs cleaning up, hacked in a mk_pte and __mk_pte... will clean up later.. our mk_pte is being use incorrectly in some VAX code so I needed __mk_pte. +/* D.A. May 2001 - FIXME: this needs cleaning up, hacked in a mk_pte and + __mk_pte... will clean up later.. our mk_pte is being use incorrectly + in some VAX code so I needed __mk_pte. */ -static inline pte_t __mk_pte(void *page, pgprot_t pgprot) + +static inline pte_t __mk_pte(unsigned long int page, pgprot_t pgprot) { pte_t pte; - pte.pte = (__pa(page) >> PAGELET_SHIFT) | pgprot_val(pgprot); + pte_val(pte) = (__pa(page) >> PAGELET_SHIFT) | pgprot_val(pgprot); return pte; } #define mk_pte(page, pgprot) __mk_pte(((page)-mem_map)<<PAGE_SHIFT,(pgprot)) /* This takes a physical page address that is used by the remapping functions */ -static inline pte_t mk_pte_phys(void *physpage, pgprot_t pgprot) +static inline pte_t mk_pte_phys(unsigned long int physpage, pgprot_t pgprot) { pte_t pte; - pte.pte = ((unsigned long)(physpage) >> PAGELET_SHIFT) | pgprot_val(pgprot); + pte_val(pte) = ((unsigned long)(physpage) >> PAGELET_SHIFT) | pgprot_val(pgprot); return pte; } @@ -196,17 +204,16 @@ /* who needs that -extern inline int pte_read(pte_t pte) { return !(pte_val(pte) & _PAGE_INVALID); } -extern inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_INVALID); } -extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) |= _PAGE_INVALID; return pte; } -extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) |= _PAGE_INVALID; return pte; } -extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) &= _PAGE_INVALID; return pte; } -extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) &= _PAGE_INVALID; return pte; } -*/ + * extern inline int pte_read(pte_t pte) { return !(pte_val(pte) & _PAGE_INVALID); } + * extern inline int pte_exec(pte_t pte) { return !(pte_val(pte) & _PAGE_INVALID); } + * extern inline pte_t pte_rdprotect(pte_t pte) { pte_val(pte) |= _PAGE_INVALID; return pte; } + * extern inline pte_t pte_exprotect(pte_t pte) { pte_val(pte) |= _PAGE_INVALID; return pte; } + * extern inline pte_t pte_mkread(pte_t pte) { pte_val(pte) &= _PAGE_INVALID; return pte; } + * extern inline pte_t pte_mkexec(pte_t pte) { pte_val(pte) &= _PAGE_INVALID; return pte; } + */ /* * these manipulate various bits in each hwpte. - * */ static inline pte_t pte_wrprotect(pte_t pte) { @@ -235,6 +242,12 @@ return pte; } +static inline pte_t pte_mkinvalid(pte_t pte) +{ + pte_val(pte) &= ~_PAGE_VALID; + return pte; +} + /* software only - only bother with first pagelet pte in the pagecluster */ static inline pte_t pte_mkold(pte_t pte) { @@ -261,9 +274,31 @@ static inline int pte_none(pte_t pte) { return (!pte_val(pte)); } static inline int pte_present(pte_t pte) { return (pte_val(pte) & _PAGE_VALID); } + +extern pte_t * pte_offset(pmd_t * dir, unsigned long address); + +/* items to manipulate a hwpte (for the S0 tables ) */ + +static inline void set_hwpte(hwpte_t *ptep, hwpte_t pte) +{ + *ptep = pte; +} + +static inline hwpte_t mk_hwpte(void *page, pgprot_t pgprot) +{ + hwpte_t hwpte; + hwpte_val(hwpte) = (__pa(page) >> PAGELET_SHIFT) | pgprot_val(pgprot); + return hwpte; +} + +static inline int hwpte_none(hwpte_t pte) { return !hwpte_val(pte); } +static inline int hwpte_present(hwpte_t pte) { return hwpte_val(pte) & _PAGE_VALID; } + +static inline hwpte_t hwpte_mkinvalid(hwpte_t pte) +{ + hwpte_val(pte) &= ~_PAGE_VALID; + return pte; +} -/* find an entry in a pagetable */ -#define pte_offset(pmd, address) \ -((pte_t *) ( ((pgd_t *)(pmd))->br + ((address & 0x3fffffff)>> PAGE_SHIFT)*BYTES_PER_PTE_T)) #endif Index: pgalloc.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pgalloc.h,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- pgalloc.h 2001/06/26 19:01:11 1.8 +++ pgalloc.h 2001/07/31 17:33:26 1.9 @@ -1,7 +1,7 @@ #ifndef __ASM_VAX_MM_PGALLOC_H #define __ASM_VAX_MM_PGALLOC_H -/* atp 2001. pgalloc.h for VAX architecture. */ +/* Copyright atp 1998-2001. pgalloc.h for VAX architecture. */ /* * Fixmes: * 1) the pte_alloc/freeing stuff. Check Constraints here @@ -16,6 +16,14 @@ /* * (c) Copyright Dave Airlie 2001 - ai...@li... * -- re-write for fixed sized processes + * + * atp Jun 2001 remove fixed size processes, use 3 level page table and pte slots. + * atp Jun-Jul 2001 - complete rewrite. + * + * each 'pgd' spans an address range of 0x40000000 bytes. + * each page of 'ptes' spans an address range of 0x80000 bytes + * So, there are 0x800 pages of 'ptes' per pgd. Keeping track of which page + * is mapped where, requires a pmd with 0x800 entries. */ #include <asm/processor.h> #include <linux/threads.h> @@ -25,6 +33,7 @@ #ifndef CONFIG_SMP extern struct pgtable_cache_struct { unsigned long *pgd_cache; + unsigned long pgd_slots_used; unsigned long *pte_cache; unsigned long pgtable_cache_sz; } quicklists; @@ -38,102 +47,66 @@ #define pmd_quicklist ((unsigned long *)0) #define pte_quicklist (quicklists.pte_cache) #define pgtable_cache_size (quicklists.pgtable_cache_sz) +#define pgd_slots_used (quicklists.pgd_slots_used) - -/* - * traditional two-level paging, page table allocation routines: - */ - -extern __inline__ pmd_t *get_pmd_fast(void) -{ - return (pmd_t *)0; -} - -extern __inline__ void free_pmd_fast(pmd_t *pmd) { } -extern __inline__ void free_pmd_slow(pmd_t *pmd) { } - -extern inline pmd_t * pmd_alloc(pgd_t *pgd, unsigned long address) -{ - if (!pgd) - BUG(); - return (pmd_t *) pgd; -} - - /* * Allocate and free page tables. The xxx_kernel() versions are * used to allocate a kernel page table - this turns on ASN bits * if any. */ -#if 0 -extern pgd_t *get_pgd_slow(void); -#else -extern __inline__ pgd_t *get_pgd_slow(void) + +extern pgd_t *pgd_alloc(void); +extern pgd_t *get_pgd_fast(void); + +extern __inline__ void free_pgd_fast(pgd_t *pgd) { - /* - * this is rather wasteful, as only 6 longwords are - * used in the entire 4kb page. Perhaps we can do something - * smarter here by using the quicklists to pack the pgds into - * a single page. - */ - pgd_t *ret = (pgd_t *)__get_free_page(GFP_KERNEL); - - if (ret) { - /* Allocate space for the p0/p1 page tables */ - /* allocate 192 pages at 4096 bytes each for page tables? */ - ret[0].br = (unsigned long)vmalloc(192 * PAGE_SIZE); - if (ret[0].br==0) - { - printk("page_tables:vmalloc failed to allocate a page directory\n"); - BUG(); - return NULL; - } - memset((void *)ret[0].br, 0, 192*PAGE_SIZE); - ret[0].lr = ((160*PAGE_SIZE)>>SIZEOF_PTE_LOG2); - /* the p1br needs to be set back from the end of the p1 ptes */ - ret[1].br = (ret[0].br - 0x800000) + (192*PAGE_SIZE); - ret[1].lr = 0x40000-((32*PAGE_SIZE)>>SIZEOF_PTE_LOG2); - - printk("get_pgd: p0: %8lX, %8lX, p1: %8lX, %8lx\n", ret[0].br, ret[0].lr, ret[1].br, ret[1].lr); - - /* set the s0 region, from the master copy in swapper_pg_dir */ - memcpy(ret + USER_PTRS_PER_PGD, swapper_pg_dir + USER_PTRS_PER_PGD, (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); - } - return ret; + *(unsigned long *)pgd = (unsigned long) pgd_quicklist; + pgd_quicklist = (unsigned long *) pgd; + pgtable_cache_size++; } -#endif -extern __inline__ pgd_t *get_pgd_fast(void) +extern __inline__ void free_pgd_slow(pgd_t *pgd) { - unsigned long *ret; + /* we dont do this at present */ +} - if ((ret = pgd_quicklist) != NULL) { - pgd_quicklist = (unsigned long *)(*ret); - ret[0] = 0; - pgtable_cache_size--; - } else - ret = (unsigned long *)get_pgd_slow(); +extern pmd_t *get_pmd_slow(void); - return (pgd_t *)ret; +/* Page Mid level directory handling routines. */ +static inline pmd_t *get_pmd_fast(void) +{ + unsigned long *ret; + + if ((ret = (unsigned long *)pte_quicklist) != NULL) { + pte_quicklist = (unsigned long *)(*ret); + ret[0] = ret[1]; + pgtable_cache_size--; + } + return (pmd_t *)ret; } -extern __inline__ void free_pgd_fast(pgd_t *pgd) +static inline void free_pmd_fast(pmd_t *pmd) { - *(unsigned long *)pgd = (unsigned long) pgd_quicklist; - pgd_quicklist = (unsigned long *) pgd; - pgtable_cache_size++; + *(unsigned long *)pmd = (unsigned long) pte_quicklist; + pte_quicklist = (unsigned long *) pmd; + pgtable_cache_size++; } -extern __inline__ void free_pgd_slow(pgd_t *pgd) +static inline void free_pmd_slow(pmd_t *pmd) { - vfree((void *)pgd[0].br); - free_page((unsigned long)pgd); + free_page((unsigned long)pmd); } +/* in arch/vax/mm/pgalloc.c */ +extern pmd_t *pmd_alloc(pgd_t *pgd, unsigned long address); +extern void pmd_free(pmd_t *pmd); +extern void pte_free(pte_t *pte); +extern unsigned long get_pageaddr_from_pte(pte_t *ptep); -extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset); +extern pte_t *get_pte_slow(void); extern pte_t *get_pte_kernel_slow(pmd_t *pmd, unsigned long offset); -extern void remap_and_clear_pte_page(pgd_t *pagetable, pte_t *page, unsigned long pte_page); +extern void remap_and_clear_pte_page(pmd_t *s0addr, pte_t *page); +extern void remap_pte_invalidate(pmd_t *s0addr); extern __inline__ pte_t *get_pte_fast(void) { @@ -158,49 +131,30 @@ extern __inline__ void free_pte_slow(pte_t *pte) { pte_clear(pte); -/* free_page((unsigned long)pte);*/ + free_page((unsigned long)pte); } -#define pte_free_kernel(pte) free_pte_slow(pte) -#define pte_free(pte) free_pte_slow(pte) -#define pgd_free(pgd) free_pgd_slow(pgd) -#define pgd_alloc() get_pgd_fast() +extern __inline__ void page_clear(pte_t *pte) {memset(pte, 0, PAGE_SIZE);} -/* atp jun 01, moved these to arch/vax/mm/pgalloc.c */ -/* Allocate a new page for a page table for the kernel */ -extern pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address); -extern pte_t *pte_alloc(pmd_t *pmd, unsigned long address); +#define pte_free_kernel(pte) free_pte_fast(pte) +#define pgd_free(pgd) free_pgd_fast(pgd) + /* * allocating and freeing a pmd is trivial: the 1-entry pmd is * inside the pgd, so has no extra memory associated with it. */ -#define pmd_free(pmd) free_pmd_slow(pmd) - #define pmd_free_kernel pmd_free #define pmd_alloc_kernel pmd_alloc -extern int do_check_pgt_cache(int, int); +/* atp jun 01, moved these to arch/vax/mm/pgalloc.c */ +/* Allocate a new page for a page table for the kernel */ +extern pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address); +extern pte_t *pte_alloc(pmd_t *pmd, unsigned long address); +extern pte_t * pte_alloc_one(pmd_t *pmd); -/* I cant find a reference to this in the generic or arch specific code - * -- it used to be called from linux/mm/vmalloc.c, but is no longer */ -/* extern inline void set_pgdir(unsigned long address, pgd_t entry) - * { - * struct task_struct * p; - * pgd_t *pgd; - * - * read_lock(&tasklist_lock); - * for_each_task(p) { - * if (!p->mm) - * continue; - * *pgd_offset(p->mm,address) = entry; - * } - * read_unlock(&tasklist_lock); - * for (pgd = (pgd_t *)pgd_quicklist; pgd; pgd = (pgd_t *)*(unsigned long *)pgd) - * pgd[address >> PGDIR_SHIFT] = entry; - * } - */ +extern int do_check_pgt_cache(int, int); /* tlb routines */ Index: pgtable.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/pgtable.h,v retrieving revision 1.13 retrieving revision 1.14 diff -u -r1.13 -r1.14 --- pgtable.h 2001/07/21 11:58:51 1.13 +++ pgtable.h 2001/07/31 17:33:26 1.14 @@ -1,4 +1,7 @@ /* (c) 2001 Vax Porting Project, atp, kenn, airlied */ + +/* FIXME: this is a mess its confusing and badly documented + * - needs cleaning up atp jul 2001 */ #ifndef _VAX_MM_PGTABLE_H #define _VAX_MM_PGTABLE_H @@ -20,6 +23,9 @@ /* the pagelet stuff */ #include <asm/mm/pgtable_pagelet.h> +/* TASK address space sizing, for sizing SPT and so forth */ +#include <asm/mm/task.h> + /* * See Documentation/vax/memory.txt * for up to date memory layout @@ -42,23 +48,29 @@ /* entries is (1024 * 1024) >> PAGELET_SIZE */ #define SPT_HWPTES_IOMAP (SPT_MAX_IOMAP<<1) #define SPT_PTES_IOMAP (SPT_MAX_IOMAP >> 2) - /*>> (PAGE_SHIFT-10)) */ + /*/>> (PAGE_SHIFT-10)) */ /* FIXME: (PAGE_SHIFT-10) is hardwired here to 2. asm bug in head.S */ #define SPT_HWPTES_VMALLOC (SPT_MAX_VMALLOC << 1) #define SPT_PTES_VMALLOC (SPT_MAX_VMALLOC >> 2) #define SPT_BASE ((unsigned long)( (swapper_pg_dir[2]).br )) -/* Length register is in words.. shift left 2 to get bytes */ -#define SPT_SIZE ((unsigned long)( (swapper_pg_dir[2]).lr ) << 2) +/* SPT_LEN can be an lvalue, and is the length in longwords */ +#define SPT_LEN ((unsigned long)( (swapper_pg_dir[2]).lr )) +/* SPT_SIZE is the size in BYTES */ +#define SPT_SIZE ((unsigned long)( (swapper_pg_dir[2]).lr ) << 2) -/* I'm not sure these are ok. I've only tested the results of - * These in the interrupt guard page routine in arch/vax/kernel/interrupt.c - * if they are 4k ptes then set_pte needs to be used on the - * results, +/* + * Macros to get page table addresses + offsets. + * + * if they are 4k ptes then set_pte needs to be used on the results, */ + /* macro to get linear page table entry for a physical address */ -#define GET_HWSPTE_PHYS(x) ((hwpte_t *)(SPT_BASE + ((x) >> (PAGELET_SHIFT-SIZEOF_PTR_LOG2)))) -#define GET_SPTE_PHYS(x) ((pte_t *)(SPT_BASE + ((x) >> (PAGE_SHIFT-SIZEOF_PTE_LOG2)))) +#define GET_HWSPTE_PHYS(x) ((hwpte_t *)(SPT_BASE + ( ((x) >> PAGELET_SHIFT) << SIZEOF_PTR_LOG2) )) + +/* this is like it is for a reason - we need to wipe out the lower bits, the old + * calculation using page_shift-sizeof_pte_log2 gave the wrong answer sometimes */ +#define GET_SPTE_PHYS(x) ((pte_t *)(SPT_BASE + ( ((x) >> PAGE_SHIFT) << SIZEOF_PTE_LOG2))) /* macro to get linear page table entry for a virtual address (only works for addresses in S0 space) */ @@ -76,23 +88,39 @@ space waste precious SPTEs. */ - /* the previous definition of VMALLOC START relied on the - * VAX phy memory being an exact 4k multiple, - * my VAX has 7f1f hw-pages so isn't aligned on 4K - * workout the VMALLOC_START from the vmallocmap_base and the - * system base register.- - */ +/* the previous definition of VMALLOC START relied on the + * VAX phy memory being an exact 4k multiple, + * my VAX has 7f1f hw-pages so isn't aligned on 4K + * workout the VMALLOC_START from the vmallocmap_base and the + * system base register.- + */ + +/* VMALLOC_OFFSET is the gap between the end of mapping of physical + * ram and the start of VMALLOC ?? */ #define VMALLOC_OFFSET (SPT_MAX_IOMAP * 1024) - /*#define VMALLOC_START ((unsigned long) high_memory + VMALLOC_OFFSET)*/ #define VMALLOC_START (PAGE_OFFSET+((vmallocmap_base-swapper_pg_dir[2].br)<<(PAGELET_SHIFT-2))) #define VMALLOC_VMADDR(x) ((unsigned long)(x)) #define VMALLOC_END (VMALLOC_START + (SPT_MAX_VMALLOC * 1024)) +/* Start of task page table area - the variables this is based on + * are defined in asm-vax/mm/task.h */ + +/* address in S0 space of where the process page table area starts and ends.*/ +#define TASKPTE_START PTE_TASK_ALIGN(VMALLOC_END) +#define TASKPTE_END (TASKPTE_START+(PTE_TASK_SLOTSIZE * TASK_MAXUPRC)) +/* the number of hwptes to map this space */ +#define SPT_HWPTES_TASKPTE (((PTE_TASK_SLOTSIZE)>>PAGELET_SHIFT)*TASK_MAXUPRC) +#define SPT_PTES_TASKPTE (SPT_HWPTES_TASKPTE >> 3) + +/* find a slot in the pagetable area for pgd (x), x is 0->TASK_MAXUPRC-1 */ +#define GET_TASKSLOT(x) (TASKPTE_START+((x) * PTE_TASK_SLOTSIZE)) + + /* page table for 0-4MB for everybody */ /* This is a c reference to the start of the system page table * (see arch/vax/boot/head.S). The spt is initialised to cover physical * memory by early boot code, based on VMB supplied information. Further - * expansion happens later in the boot sequence */ + * expansion happens later in the boot sequence in paging_init */ extern pte_t *pg0; /* Number of SPTEs in system page table */ @@ -135,7 +163,7 @@ #define SWP_TYPE(x) (((x).val >> 1) & 0x3f) #define SWP_OFFSET(x) ((x).val >> 8) #define SWP_ENTRY(type, offset) ((swp_entry_t) { ((type) << 1) | ((offset) << 8) }) -#define pte_to_swp_entry(x) ((swp_entry_t) { (x).pte }) +#define pte_to_swp_entry(x) ((swp_entry_t) { pte_val(x) }) #define swp_entry_to_pte(x) ((pte_t) { (x).val }) /* Memory sizing. You'll need to #include <asm/rpb.h> to get Index: tlb.h =================================================================== RCS file: /cvsroot/linux-vax/kernel-2.4/include/asm-vax/mm/tlb.h,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- tlb.h 2001/02/15 01:17:23 1.1 +++ tlb.h 2001/07/31 17:33:26 1.2 @@ -16,7 +16,6 @@ * VAX hw ref manual pg 216. can use mtpr to either invalidate single * (TBIS) or all (TBIA) TLB entries. In addition LDPCTX will * invalidate all process virtual address translations. - * FIXME: adopting sledgehammer (trust me i know what I'm doing) approach */ #define __flush_tlb() \ |