Skip to content

Commit

Permalink
[kernel] Split XMS/DMA buffer from track cache for BIOS and DF drivers
Browse files Browse the repository at this point in the history
  • Loading branch information
ghaerr committed Nov 4, 2024
1 parent 49535f2 commit 152aaae
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 37 deletions.
31 changes: 17 additions & 14 deletions elks/arch/i86/drivers/block/bioshd.c
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ static struct gendisk bioshd_gendisk = {

static void BFPROC set_cache_invalid(void)
{
if (cache_drive) debug_cache2("INV%d ", cache_drive - drive_info);
if (cache_drive) debug_cache("INV%d ", bios_drive_map[cache_drive - drive_info]);
cache_drive = NULL;
}

Expand Down Expand Up @@ -525,11 +525,11 @@ static void BFPROC get_chst(struct drive_infot *drivep, sector_t *start_sec,
#if FULL_TRACK
if (fulltrack) {
int save = *s;
int max_sectors = DMASEGSZ / drivep->sector_size;
int max_sectors = TRACKSEGSZ / drivep->sector_size;
if (*s - 1 < max_sectors) { /* adjust start sector backwards for full track read*/
*s = 1;
*t = max_sectors;
} else { /* likely 2880k: limit to size of DMASEG buffer */
} else { /* likely 2880k: limit to size of TRACKSEG buffer */
*s = max_sectors + 1;
*t = drivep->sectors - *s + 1;
}
Expand Down Expand Up @@ -559,8 +559,6 @@ static int BFPROC do_readwrite(struct drive_infot *drivep, sector_t start, char
if (cmd == READ) debug_bios("bioshd(%x): read lba %ld count %d\n",
drive, start, this_pass);

errs = MAX_ERRS; /* BIOS disk reads should be retried at least five times */
do {
#pragma GCC diagnostic ignored "-Wshift-count-overflow"
usedmaseg = seg >> 16; /* will be nonzero only if XMS configured and XMS buffer */
if (!usedmaseg) {
Expand All @@ -576,13 +574,16 @@ static int BFPROC do_readwrite(struct drive_infot *drivep, sector_t start, char
offset = 0;
if (cmd == WRITE) /* copy xms buffer down before write*/
xms_fmemcpyw(0, DMASEG, buf, seg, this_pass*(drivep->sector_size >> 1));
set_cache_invalid();
//set_cache_invalid(); /* don't invalidate cache - not shared */
} else {
segment = (seg_t)seg;
offset = (unsigned) buf;
}
debug_cache("%s%d CHS %d/%d/%d count %d\n",
cmd==WRITE? "WR": "RD", drive, cylinder, head, sector, this_pass);
errs = MAX_ERRS; /* BIOS disk reads should be retried at least five times */
do {
debug_cache("%s%s%d CHS %d/%d/%d count %d\n",
cmd==WRITE? "WR": "RD", usedmaseg? "X": "", drive, cylinder, head, sector,
this_pass);
debug_bios("bioshd(%x): cmd %d CHS %d/%d/%d count %d\n",
drive, cmd, cylinder, head, sector, this_pass);

Expand All @@ -602,16 +603,18 @@ static int BFPROC do_readwrite(struct drive_infot *drivep, sector_t start, char
if (usedmaseg) {
if (cmd == READ) /* copy DMASEG up to xms*/
xms_fmemcpyw(buf, seg, 0, DMASEG, this_pass*(drivep->sector_size >> 1));
set_cache_invalid();
//set_cache_invalid(); /* don't invalidate cache - not shared */
}
if (cmd == WRITE && drivep == cache_drive)
set_cache_invalid(); /* cache isn't updated on writes */
return this_pass;
}

#ifdef CONFIG_TRACK_CACHE /* use track-sized sector cache*/
static sector_t cache_startsector;
static sector_t cache_endsector;

/* read from start sector to end of track into DMASEG track buffer, no retries*/
/* read from start sector to end of track into TRACKSEG track buffer, no retries*/
static void BFPROC do_readtrack(struct drive_infot *drivep, sector_t start)
{
unsigned int cylinder, head, sector, num_sectors;
Expand All @@ -621,8 +624,8 @@ static void BFPROC do_readtrack(struct drive_infot *drivep, sector_t start)
drive = bios_drive_map[drive];
get_chst(drivep, &start, &cylinder, &head, &sector, &num_sectors, 1);

if (num_sectors > (DMASEGSZ / drivep->sector_size))
num_sectors = DMASEGSZ / drivep->sector_size;
if (num_sectors > (TRACKSEGSZ / drivep->sector_size))
num_sectors = TRACKSEGSZ / drivep->sector_size;

do {
debug_cache("\nTR%d %lu(CHS %u,%u,%u-%u) ", drive, start>>1, cylinder, head,
Expand All @@ -632,7 +635,7 @@ static void BFPROC do_readtrack(struct drive_infot *drivep, sector_t start)

bios_set_ddpt(drivep->sectors);
error = bios_disk_rw(BIOSHD_READ, num_sectors, drive,
cylinder, head, sector, DMASEG, 0);
cylinder, head, sector, TRACKSEG, 0);
if (error) {
printk("bioshd(%x): track read retry #%d CHS %d/%d/%d count %d\n",
drive, errs + 1, cylinder, head, sector, num_sectors);
Expand Down Expand Up @@ -665,7 +668,7 @@ static int BFPROC cache_valid(struct drive_infot *drivep, sector_t start, char *
offset = (int)(start - cache_startsector) * drivep->sector_size;
debug_bios("bioshd(%x): cache hit lba %ld\n",
bios_drive_map[drivep-drive_info], start);
xms_fmemcpyw(buf, seg, (void *)offset, DMASEG, drivep->sector_size >> 1);
xms_fmemcpyw(buf, seg, (void *)offset, TRACKSEG, drivep->sector_size >> 1);
return 1;
}

Expand Down
6 changes: 3 additions & 3 deletions elks/arch/i86/drivers/block/directfd.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,10 +137,10 @@ char USE_IMPLIED_SEEK = 0; /* =1 for QEMU with 360k/AT stretch floppies (not rea
#define TIMEOUT_CMD_COMPL (6 * HZ) /* 6 secs wait for FDC command complete */

/* locations for cache and bounce buffers */
#define CACHE_SEG DMASEG /* track cache at DMASEG:0 (shared with BIOS driver) */
#define CACHE_OFF 0
#define BOUNCE_SEG DMASEG /* share bounce buffer with track cache at DMASEG:0 */
#define BOUNCE_SEG TRACKSEG /* share bounce buffer with track cache at TRACKSEG:0 */
#define BOUNCE_OFF 0
#define CACHE_SEG TRACKSEG /* track cache at TRACKSEG:0 (same as BIOS FD driver) */
#define CACHE_OFF 0

#define FLOPPY_DMA 2 /* hardwired on old PCs */

Expand Down
38 changes: 25 additions & 13 deletions elks/include/linuxmt/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -103,27 +103,39 @@
#define DEF_SETUPSEG DEF_INITSEG + 0x20
#define DEF_SYSMAX 0x2F00 /* maximum system size (=.text+.fartext+.data) */

/* Segment DMASEG up to DMASEGEND is used as a bounce buffer of at least 1K (=BLOCKSIZE)
* below the first 64K boundary (=0x1000:0) for use with the old 8237 DMA controller.
* If floppy track caching is enabled, this area is also used for the track buffer
* for direct DMA access using multisector I/O.
* Following DMASEGEND is the kernel code and data at REL_SYSSEG.
/* Segment DMASEG up to DMASEGEND is used for the XMS/DMA bounce buffer and track cache.
* Following DMASEGEND is the kernel code at REL_SYSSEG (or kernel data for ROM configs).
*
* A "bounce buffer" is configured below the first 64K boundary for use with
* old 8237 DMA controller which wraps addresses wider than 16-bits on PC/XT systems.
* If floppy track caching is enabled, the track buffer is also configured in
* low memory for direct DMA access usig multisector I/O.
* The DF driver uses the first sector of its track cache for the XMS/DMA buffer.
* In contrast, the BIOS FD/HD driver is configured to use an XMS/DMA buffer
* outside its track cache; thus the complicated defines below.
*/

#if defined(CONFIG_BLK_DEV_BFD) || defined(CONFIG_BLK_DEV_BHD)
#define DMASEGSZ 0x0400 /* BLOCK_SIZE (1024) for external XMS/DMA buffer */
#else
#define DMASEGSZ 0 /* no external XMS/DMA buffer */
#endif

#if defined(CONFIG_BLK_DEV_BFD) || defined(CONFIG_BLK_DEV_BHD) || defined(CONFIG_BLK_FD)
#ifdef CONFIG_TRACK_CACHE /* floppy track buffer in low mem */
#define DMASEGSZ 0x2400 /* SECTOR_SIZE * 18 (9216) */
#define TRACKSEGSZ 0x2400 /* SECTOR_SIZE * 18 (9216) */
#else
#define DMASEGSZ 0x0400 /* BLOCK_SIZE (1024) */
#define TRACKSEGSZ 0x0400 /* BLOCK_SIZE (1024) */
#endif
#define TRACKSEG (DMASEG+(DMASEGSZ>>4))
#define DMASEGEND (DMASEG+(DMASEGSZ>>4)+(TRACKSEGSZ>>4))
#else
#define DMASEGEND DMASEG /* no DMASEG buffer */
#endif
#define DMASEGEND (DMASEG+(DMASEGSZ>>4))

#ifdef CONFIG_ROMCODE
#if defined(CONFIG_BLK_DEV_BFD) || defined(CONFIG_BLK_DEV_BHD) /* BIOS disk driver*/
#define DMASEG 0x80 /* 0x400 bytes floppy sector buffer */
#define DMASEG 0x80 /* start of floppy sector buffer */
#define KERNEL_DATA DMASEGEND /* kernel data segment */
#else
#define KERNEL_DATA 0x080 /* kernel data segment */
#endif
#define SETUP_DATA CONFIG_ROM_SETUP_DATA
#endif

Expand Down
12 changes: 5 additions & 7 deletions emu86.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,18 @@
# Kernel image @ segment 0xE000 (as 64K BIOS extension)
# Root filesystem @ segment 0x8000 (assumes 512K RAM & 512K ROM)

# 8088 version using emu-rom-full.config from './buildimages.sh fast'
# 8088 ROM version using emu-rom-full.config from './buildimages.sh fast'
exec emu86 -w 0xe0000 -f image/rom-8088.bin -w 0x80000 -f image/romfs-8088.bin ${1+"$@"}

# just built rom version using 'make'
exec emu86 -w 0xe0000 -f elks/arch/i86/boot/Image -w 0x80000 -f image/romfs.bin ${1+"$@"}
# just built ROM version using 'make'
#exec emu86 -w 0xe0000 -f elks/arch/i86/boot/Image -w 0x80000 -f image/romfs.bin ${1+"$@"}

# For ELKS Full ROM Configuration:
# ELKS must be configured minimally with 'cp emu86-rom-full.config .config'
# This adds MINIX/FAT filesytems with BIOS driver

exec emu86 -w 0xe0000 -f elks/arch/i86/boot/Image -w 0x80000 -f image/romfs.bin -I image/fd1440.bin ${1+"$@"}
#exec emu86 -w 0xe0000 -f rom-8088.bin -w 0x80000 -f image/romfs.bin -I image/fd1440.img ${1+"$@"}

# For ELKS disk image Configuration:
# ELKS must be configured with 'cp emu86-disk.config .config'
# This uses headless console, HLT on idle, no CONFIG_IDE_PROBE

exec emu86 -I image/fd1440.bin ${1+"$@"}
#exec emu86 -I image/fd1440.img ${1+"$@"}

0 comments on commit 152aaae

Please sign in to comment.