From: Alan Cox Date: Tue, 18 Nov 2014 20:37:10 +0000 (+0000) Subject: bank32: make passive provision for awkward boxes with low 32K switching X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=5e0d6cfa145382c00342f945cf95f389164abf4b;p=FUZIX.git bank32: make passive provision for awkward boxes with low 32K switching This allows you to define them as a 32K paged system and use the provided swap and page hooks, plus your switch functions to copy blocks between the spare parts of the high 32K and the pages they are stashed in. This means that with a typical usage model of a single large app performance will basically be as good as a sensible layout, and only if you have two larger apps actively running at once will it degrade much. This will be pretty much essential to cover the uBee and the N8VEM-2. --- diff --git a/Kernel/bank32k.c b/Kernel/bank32k.c index 84e769e8..5b193fb4 100644 --- a/Kernel/bank32k.c +++ b/Kernel/bank32k.c @@ -3,6 +3,11 @@ #include #ifdef CONFIG_BANK32 + +#ifndef bank32_invalidate_cache +#define bank32_invalidate_cache(x) do {} while(0) +#endif + /* * Map handling: We have flexible paging. Each map table consists of a set of pages * with the last page repeated to fill any holes. @@ -13,6 +18,24 @@ * * We have at least one potential oddball to cater for here later. The Sam Coupe has * 32K banking but you can pick blocks to bank high or low on a 16K alignment. + * + * If you have a system which has the top 32K fixed and the lower 32K as pages + * then you have a choice to make. You can use the fixed bank module and limit + * process sizes to 32K or you can do this + * + * - Build the kernel to use a low 32K bank and shove the rest as high up as + * you can + * - On switchin/out do the uarea copies as required already + * - Use the remaining upper space as a cache for the bits of the top of big + * processes and remember the current cached page + * - In switchin check if the two pages are different, if so check the top + * page against the cache and copy out the old cache to its true page, and + * then copy in the new one + * - Provide a bank32_invalidate_cache definition to clear the cached page + * when it is freed. + * + * If you are also doing swapping then you need to account for the cache + * by providing a swap_flush_cache() method (see swap.c) * */ @@ -36,8 +59,10 @@ void pagemap_free(ptptr p) { uint8_t *ptr = (uint8_t *) & p->p_page; pfree[pfptr--] = *ptr; - if (*ptr != ptr[1]) + if (*ptr != ptr[1]) { pfree[pfptr--] = ptr[1]; + bank32_invalidate_cache(ptr[1]); + } } static int maps_needed(uint16_t top) diff --git a/Kernel/swap.c b/Kernel/swap.c index f2cedbb7..f9f64545 100644 --- a/Kernel/swap.c +++ b/Kernel/swap.c @@ -16,6 +16,9 @@ #define UDATA_BLOCKS 0 #endif +#ifndef swap_flush_cache +#define swap_flush_cache(p) do {} while(0) +#endif uint8_t *swapbase; unsigned int swapcnt; @@ -74,6 +77,7 @@ int swapout(ptptr p) /* Are we out of swap ? */ if (swapptr == 0) return ENOMEM; + swap_flush_cache(p); map = swapmap[--swapptr]; blk = map * SWAP_SIZE; #ifdef UDATA_SWAPSIZE