From: Alan Cox Date: Mon, 20 Apr 2015 21:26:14 +0000 (+0100) Subject: swap: Assorted fixes and changes X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=7cfddab9dfd5c9c25685a92f417973f6bd5ebf17;p=FUZIX.git swap: Assorted fixes and changes The swapper writes memory out in chunks that it knows fit one "page", whether that is a bank number of a page number. It also provides a swap_map function so you can map swap. Rather than pass the process it passes the correct page number for each write and no write crosses a bank. Also allow the use of page2 for memory while swapping. That just requires the value to be saved. This changes the swap API so various drivers will need fixes and testing. It should however take us closer to having the swap interface properly split from the memory model, and to allowing swap in awkward cases like 16K banking. --- diff --git a/Kernel/bank16k.c b/Kernel/bank16k.c index 00b8a256..2d5304a8 100644 --- a/Kernel/bank16k.c +++ b/Kernel/bank16k.c @@ -171,8 +171,7 @@ int swapout(ptptr p) uint16_t base = SWAPBASE; uint16_t size = (0x4000 - SWAPBASE) >> 9; uint16_t i; - - swapproc = p; + uint8_t *pt = (uint8_t *)&p->page; if (page) panic("process already swapped!\n"); @@ -187,7 +186,7 @@ int swapout(ptptr p) blk = map * SWAP_SIZE; /* Write the app (and possibly the uarea etc..) to disk */ for (i = 0; i < 4; i ++) { - swapwrite(SWAPDEV, blk, size, (uint8_t *)base); + swapwrite(SWAPDEV, blk, size, base, *pt++); base += 0x4000; /* Last bank is determined by SWAP SIZE. We do the maths in 512's (0x60 = 0xC000) */ @@ -209,12 +208,13 @@ int swapout(ptptr p) /* * Swap ourself in: must be on the swap stack when we do this */ -void swapin(ptptr p) +void swapin(ptptr p, uint16_t map) { - uint16_t blk = p->p_page2 * SWAP_SIZE; + uint16_t blk = map * SWAP_SIZE; uint16_t base = SWAPBASE; uint16_t size = (0x4000 - SWAPBASE) >> 9; uint16_t i; + uint8_t *pt = (uint8_t *)&p->page; #ifdef DEBUG kprintf("Swapin %x, %d\n", p, p->p_page); @@ -224,12 +224,8 @@ void swapin(ptptr p) return; } - /* Return our swap */ - swapmap_add(p->p_page2); - - swapproc = p; /* always ourself */ for (i = 0; i < 4; i ++) { - swapread(SWAPDEV, blk, size, (uint8_t *)base); + swapread(SWAPDEV, blk, size, base, *pt++); base += 0x4000; /* Last bank is determined by SWAP SIZE. We do the maths in 512's (0x60 = 0xC000) */ diff --git a/Kernel/bank16k_low.c b/Kernel/bank16k_low.c index 00696160..57255bad 100644 --- a/Kernel/bank16k_low.c +++ b/Kernel/bank16k_low.c @@ -174,8 +174,7 @@ int swapout(ptptr p) uint16_t map; uint16_t base = SWAPBASE; uint16_t size = (0x4000 - SWAPBASE) >> 9; - - swapproc = p; + uint8_t *pt = (uint8_t *)&p->page; if (page) panic("process already swapped!\n"); @@ -196,7 +195,7 @@ int swapout(ptptr p) /* Write the app (and possibly the uarea etc..) to disk */ for (i = 0; i < 4; i ++) { - swapwrite(SWAPDEV, blk, size, base); + swapwrite(SWAPDEV, blk, size, base, *pt++); base += 0x4000; /* Last bank is determined by SWAP SIZE. We do the maths in 512's (0x60 = 0xC000) */ @@ -218,11 +217,13 @@ int swapout(ptptr p) /* * Swap ourself in: must be on the swap stack when we do this */ -void swapin(ptptr p) +void swapin(ptptr p, uint16_t map) { - uint16_t blk = p->p_page2 * SWAP_SIZE; + uint16_t blk = map * SWAP_SIZE; uint16_t base = SWAPBASE; uint16_t size = (0x4000 - SWAPBASE) >> 9; + uint16_t i; + uint8_t *pt = (uint8_t *)&p->page; #ifdef DEBUG kprintf("Swapin %x, %d\n", p, p->p_page); @@ -232,9 +233,6 @@ void swapin(ptptr p) return; } - /* Return our swap */ - swapmap_add(p->p_page2); - /* This may need other tweaks as its a special nasty case where we don't want to overwrite the live stack but buffer and fix up in tricks.s */ @@ -243,9 +241,8 @@ void swapin(ptptr p) blk++; #endif - swapproc = p; /* always ourself */ for (i = 0; i < 4; i ++) { - swapread(SWAPDEV, blk, size, base); + swapread(SWAPDEV, blk, size, base, *pt++); base += 0x4000; /* Last bank is determined by SWAP SIZE. We do the maths in 512's (0x60 = 0xC000) */ diff --git a/Kernel/bankfixed.c b/Kernel/bankfixed.c index 127faacf..1db1d143 100644 --- a/Kernel/bankfixed.c +++ b/Kernel/bankfixed.c @@ -92,8 +92,6 @@ int swapout(ptptr p) uint16_t blk; uint16_t map; - swapproc = p; - if (!page) panic("process already swapped!\n"); #ifdef DEBUG @@ -105,8 +103,7 @@ int swapout(ptptr p) return ENOMEM; blk = map * SWAP_SIZE; /* Write the app (and possibly the uarea etc..) to disk */ - swapwrite(SWAPDEV, blk, SWAPTOP - SWAPBASE, - (uint8_t *)SWAPBASE); + swapwrite(SWAPDEV, blk, SWAPTOP - SWAPBASE, SWAPBASE, p->page); pagemap_free(p); p->p_page = 0; p->p_page2 = map; @@ -119,9 +116,9 @@ int swapout(ptptr p) /* * Swap ourself in: must be on the swap stack when we do this */ -void swapin(ptptr p) +void swapin(ptptr p, uint16_t map) { - uint16_t blk = p->p_page2 * SWAP_SIZE; + uint16_t blk = map * SWAP_SIZE; #ifdef DEBUG kprintf("Swapin %x, %d\n", p, p->p_page); @@ -130,13 +127,7 @@ void swapin(ptptr p) kprintf("%x: nopage!\n", p); return; } - - /* Return our swap */ - swapmap_add(p->p_page2); - - swapproc = p; /* always ourself */ - swapread(SWAPDEV, blk, SWAPTOP - SWAPBASE, - (uint8_t *)SWAPBASE); + swapread(SWAPDEV, blk, SWAPTOP - SWAPBASE, SWAPBASE, p->page); #ifdef DEBUG kprintf("%x: swapin done %d\n", p, p->p_page); #endif diff --git a/Kernel/include/kernel.h b/Kernel/include/kernel.h index 2ba71e98..8f972e07 100644 --- a/Kernel/include/kernel.h +++ b/Kernel/include/kernel.h @@ -745,22 +745,23 @@ extern int _select(void); #endif /* swap.c */ -extern ptptr swapproc; +extern uint16_t swappage; extern uint8_t *swapbase; extern unsigned int swapcnt; extern blkno_t swapblk; extern int swapread(uint16_t dev, blkno_t blkno, unsigned int nbytes, - uint8_t *buf); + uint16_t buf, uint16_t page); extern int swapwrite(uint16_t dev, blkno_t blkno, unsigned int nbytes, - uint8_t *buf); + uint16_t buf, uint16_t page); extern void swapmap_add(uint8_t swap); extern int swapmap_alloc(void); extern ptptr swapneeded(ptptr p, int selfok); extern void swapper(ptptr p); +/* These two are provided by the bank code selected for the port */ extern int swapout(ptptr p); -extern void swapin(ptptr p); +extern void swapin(ptptr p, uint16_t map); /* syscalls_fs.c, syscalls_proc.c, syscall_other.c etc */ extern void updoff(void); diff --git a/Kernel/simple.c b/Kernel/simple.c index 2e7ba952..619f206a 100644 --- a/Kernel/simple.c +++ b/Kernel/simple.c @@ -60,8 +60,6 @@ int swapout(ptptr p) uint16_t blk; uint16_t map; - swapproc = p; - if (!page) panic("process already swapped!\n"); #ifdef DEBUG @@ -74,7 +72,7 @@ int swapout(ptptr p) blk = map * SWAP_SIZE; /* Write the app (and possibly the uarea etc..) to disk */ swapwrite(SWAPDEV, blk, SWAPTOP - SWAPBASE, - SWAPBASE); + SWAPBASE, 1); p->p_page = 0; p->p_page2 = map; #ifdef DEBUG @@ -86,9 +84,9 @@ int swapout(ptptr p) /* * Swap ourself in: must be on the swap stack when we do this */ -void swapin(ptptr p) +void swapin(ptptr p, uint16_t map) { - uint16_t blk = p->p_page2 * SWAP_SIZE; + uint16_t blk = map * SWAP_SIZE; #ifdef DEBUG kprintf("Swapin %x, %d\n", p, p->p_page); @@ -98,12 +96,8 @@ void swapin(ptptr p) return; } - /* Return our swap */ - swapmap_add(p->p_page2); - - swapproc = p; /* always ourself */ swapread(SWAPDEV, blk, SWAPTOP - SWAPBASE, - SWAPBASE); + SWAPBASE, 1); #ifdef DEBUG kprintf("%x: swapin done %d\n", p, p->p_page); #endif diff --git a/Kernel/swap.c b/Kernel/swap.c index 63e87e82..11a9058e 100644 --- a/Kernel/swap.c +++ b/Kernel/swap.c @@ -15,7 +15,7 @@ uint8_t *swapbase; unsigned int swapcnt; blkno_t swapblk; -ptptr swapproc; /* Target process space */ +uint16_t swappage; /* Target page */ /* Table of available maps */ static uint8_t swapmap[MAX_SWAPS]; @@ -36,22 +36,27 @@ int swapmap_alloc(void) return 0; } +/* FIXME: clean this up by having a common i/o structure to avoid + all the mode 1 and mode 2 confusion and conversions */ + int swapread(uint16_t dev, blkno_t blkno, unsigned int nbytes, - uint8_t *buf) + uint16_t buf, uint16_t page) { - swapbase = buf; + swapbase = swap_map(buf); swapcnt = nbytes; swapblk = blkno; + swappage = page; return ((*dev_tab[major(dev)].dev_read) (minor(dev), 2, 0)); } int swapwrite(uint16_t dev, blkno_t blkno, unsigned int nbytes, - uint8_t *buf) + uint16_t buf, uint16_t page) { - swapbase = buf; + swapbase = swap_map(buf); swapcnt = nbytes; swapblk = blkno; + swappage = page; return ((*dev_tab[major(dev)].dev_write) (minor(dev), 2, 0)); } @@ -132,12 +137,15 @@ ptptr swapneeded(ptptr p, int notself) */ void swapper(ptptr p) { - pagemap_alloc(p); /* May cause a swapout */ + uint16_t map = p->p_page2; + pagemap_alloc(p); /* May cause a swapout. May also destroy + the old value of p->page2 */ #ifdef DEBUG kprintf("Swapping in %x (page %d), utab.ptab %x\n", p, p->p_page, udata.u_ptab); #endif - swapin(p); + swapin(p, map); + swapmap_add(map); #ifdef DEBUG kprintf("Swapped in %x (page %d), udata.ptab %x\n", p, p->p_page, udata.u_ptab);