Kernel: p112, n8vem-mark4: Implement /dev/rd and new /dev/mem
authorWill Sowerbutts <will@sowerbutts.com>
Sun, 8 Jan 2017 22:47:58 +0000 (22:47 +0000)
committerWill Sowerbutts <will@sowerbutts.com>
Sun, 8 Jan 2017 23:05:11 +0000 (23:05 +0000)
This implements the new /dev/mem and /dev/rd drivers for the Z180
based platforms.

p112: Note that the ROM disk is not useful on P112 as the ROM is limited
to 32KB in size and is unmapped from the CPU address space.

16 files changed:
Kernel/cpu-z180/z180.s
Kernel/dev/devrd_z180_hw.s [new file with mode: 0644]
Kernel/platform-n8vem-mark4/Makefile
Kernel/platform-n8vem-mark4/config.h
Kernel/platform-n8vem-mark4/devices.c
Kernel/platform-n8vem-mark4/discard.c
Kernel/platform-n8vem-mark4/fuzix.lnk
Kernel/platform-n8vem-mark4/kernel.def
Kernel/platform-n8vem-mark4/mark4.s
Kernel/platform-p112/Makefile
Kernel/platform-p112/config.h
Kernel/platform-p112/devices.c
Kernel/platform-p112/discard.c
Kernel/platform-p112/fuzix.lnk
Kernel/platform-p112/kernel.def
Kernel/platform-p112/p112.s

index d1907b8..c427fec 100644 (file)
@@ -7,6 +7,7 @@
         ; exported symbols
         .globl z180_init_hardware
         .globl z180_init_early
+        .globl _init_hardware_c
         .globl _program_vectors
         .globl _copy_and_map_process
         .globl interrupt_table ; not used elsewhere but useful to check correct alignment
@@ -186,7 +187,8 @@ z180_init_hardware:
         ; Enable external interrupts (INT0/INT1/INT2) 
         ld a, #0x87
         out0 (INT_ITC), a
-        ret
+
+        jp _init_hardware_c
 
 ; -----------------------------------------------------------------------------
 ; KERNEL MEMORY BANK (only accessible when the kernel is mapped)
diff --git a/Kernel/dev/devrd_z180_hw.s b/Kernel/dev/devrd_z180_hw.s
new file mode 100644 (file)
index 0000000..2edd4a1
--- /dev/null
@@ -0,0 +1,128 @@
+; 2017-01-04 William R Sowerbutts
+
+        .module devrd_hw
+        .z180
+
+        ; exported symbols
+        .globl _rd_platform_copy
+        .globl _rd_cpy_count
+        .globl _rd_reverse
+        .globl _rd_dst_userspace
+        .globl _rd_dst_address
+        .globl _rd_src_address
+        .globl _devmem_read
+        .globl _devmem_write
+
+        .include "kernel.def"
+        .include "../kernel.def"
+        .include "../cpu-z180/z180.def"
+
+        .area _CODE
+_devmem_write:
+        ld a, #1
+        ld (_rd_reverse), a             ; 1 = write
+        jr _devmem_go
+
+_devmem_read:
+        xor a
+        ld (_rd_reverse), a             ; 0 = read
+        inc a
+_devmem_go:
+        ld (_rd_dst_userspace), a       ; 1 = userspace
+        ; load the other parameters
+        ld hl, (U_DATA__U_BASE)
+        ld (_rd_dst_address), hl
+        ld hl, (U_DATA__U_COUNT)
+        ld (_rd_cpy_count), hl
+        ld hl, (U_DATA__U_OFFSET)
+        ld (_rd_src_address), hl
+        ld hl, (U_DATA__U_OFFSET+2)
+        ld (_rd_src_address+2), hl
+        ; FALL THROUGH INTO _rd_platform_copy
+
+;=========================================================================
+; _rd_page_copy - Copy data from one physical page to another
+; See notes in devrd.h for input parameters
+;=========================================================================
+_rd_platform_copy:
+        ; save interrupt flag on stack then disable interrupts
+        ld a, i
+        push af
+        di
+
+        ; load source page number
+        ld de, (_rd_src_address+1) ; and +2
+        ld a,  (_rd_src_address+0)
+        ld b, a
+
+        ; compute destination
+        ld a,(_rd_dst_userspace)        ; are we loading into userspace memory?
+        or a
+        jr nz, rd_translate_userspace
+        ld hl, #(OS_BANK + FIRST_RAM_BANK) << 4
+        jr rd_done_translate
+rd_translate_userspace:
+        ld hl,(U_DATA__U_PAGE)          ; load page number
+        add hl, hl                      ; shift left 4 bits
+        add hl, hl
+        add hl, hl
+        add hl, hl
+rd_done_translate:
+        ; add in page offset
+        ld a,(_rd_dst_address+1)        ; top 8 bits of address
+        add a, l
+        ld l, a
+        adc a, h
+        sub l
+        ld h, a                         ; result in hl
+        ld a,(_rd_dst_address+0)
+        ld c, a
+
+        ld a,(_rd_reverse)
+        or a
+        jr z,not_reversed
+
+        ex de, hl
+        out0 (DMA_SAR0L),c
+        out0 (DMA_DAR0L),b
+        jr topbits
+not_reversed:
+        out0 (DMA_SAR0L),b
+        out0 (DMA_DAR0L),c
+topbits:
+        out0 (DMA_SAR0B),d
+        out0 (DMA_SAR0H),e
+        out0 (DMA_DAR0B),h
+        out0 (DMA_DAR0H),l
+
+        ld hl,(_rd_cpy_count)
+        out0 (DMA_BCR0L),l
+        out0 (DMA_BCR0H),h
+
+        ; make dma go
+        ld bc, #0x0240
+        out0 (DMA_DMODE), b     ; 0x02 - memory to memory, burst mode
+        out0 (DMA_DSTAT), c     ; 0x40 - enable DMA channel 0
+        ; CPU stalls until DMA burst completes
+
+        ; recover interrupt flag from stack and restore ints if required
+        pop af
+        ret po
+        ei
+        ret                     ; return with HL=_rd_cpy_count, as required by char device drivers
+
+; variables
+_rd_cpy_count:
+        .dw     0                       ; uint16_t
+_rd_reverse:
+        .db     0                       ; bool
+_rd_dst_userspace:
+        .db     0                       ; bool
+_rd_dst_address:
+        .dw     0                       ; uint16_t
+_rd_src_address:
+        .db     0                       ; uint32_t
+        .db     0
+        .db     0
+        .db     0
+;=========================================================================
index 1c1b157..bc0a82e 100644 (file)
@@ -2,15 +2,17 @@ ASRCS = crt0.s z180.s commonmem.s mark4.s ds1302-mark4.s monitor.s
 CSRCS += devices.c main.c devtty.c devsdspi.c
 DISCARD_CSRCS = discard.c
 DISCARD_DSRCS = ../dev/devide_discard.c ../dev/devsd_discard.c ../dev/ds1302_discard.c
-DSRCS = ../dev/devide.c ../dev/devsd.c ../dev/mbr.c ../dev/blkdev.c ../dev/ds1302.c
+DSRCS = ../dev/devide.c ../dev/devsd.c ../dev/mbr.c ../dev/blkdev.c ../dev/ds1302.c ../dev/devrd.c
+DASRCS = ../dev/devrd_hw.s ../dev/devrd_z180_hw.s
 
 AOBJS = $(ASRCS:.s=.rel)
 COBJS = $(CSRCS:.c=.rel)
 DISCARD_COBJS = $(DISCARD_CSRCS:.c=.rel)
 DISCARD_DOBJS = $(patsubst ../dev/%.c,%.rel, $(DISCARD_DSRCS))
 DOBJS = $(patsubst ../dev/%.c,%.rel, $(DSRCS))
+DAOBJS = $(patsubst ../dev/%.s,%.rel, $(DASRCS))
 
-OBJS  = $(AOBJS) $(COBJS) $(DOBJS) $(DISCARD_DOBJS) $(DISCARD_COBJS)
+OBJS  = $(AOBJS) $(COBJS) $(DOBJS) $(DISCARD_DOBJS) $(DISCARD_COBJS) $(DAOBJS)
 
 CROSS_CCOPTS += -I../dev/
 
@@ -27,6 +29,9 @@ $(COBJS): %.rel: %.c
 $(DOBJS): %.rel: ../dev/%.c
        $(CROSS_CC) $(CROSS_CCOPTS) -c $<
 
+$(DAOBJS): %.rel: ../dev/%.s
+       $(CROSS_AS) $(ASOPTS) $@ $<
+
 $(DISCARD_COBJS): %.rel: %.c
        $(CROSS_CC) $(CROSS_CCOPTS) $(CROSS_CC_SEGDISC) -c $<
 
index ae2d343..4017d22 100644 (file)
@@ -29,7 +29,7 @@
 
 /* We need a tidier way to do this from the loader */
 #define CMDLINE        (0x0081)  /* Location of root dev name */
-#define BOOTDEVICENAMES "hd#"
+#define BOOTDEVICENAMES "hd#,,,rd"
 
 #define NBUFS    10       /* Number of block buffers */
 #define NMOUNTS         4        /* Number of mounts at a time */
 #define CONFIG_RTC
 #define CONFIG_RTC_INTERVAL 30 /* deciseconds between reading RTC seconds counter */
 
+/* Memory backed devices */
+#define CONFIG_DEV_MEM          /* enable /dev/mem driver */
+#define CONFIG_RAMDISK          /* enable memory-backed device driver */
+#define DEV_RD_ROM_PAGES 64     /* size of the ROM disk (/dev/rd0) in 4KB pages */
+#define DEV_RD_RAM_PAGES 0      /* size of the RAM disk (/dev/rd1) in 4KB pages */
+
+#define DEV_RD_ROM_START ((uint32_t)(128-DEV_RD_ROM_PAGES) << 12)
+#define DEV_RD_RAM_START ((uint32_t)(256-DEV_RD_RAM_PAGES) << 12)
+#define DEV_RD_ROM_SIZE  ((uint32_t)DEV_RD_ROM_PAGES << 12)
+#define DEV_RD_RAM_SIZE  ((uint32_t)DEV_RD_RAM_PAGES << 12)
+
 /* Optional PropIOv2 board on ECB bus */
 //#define CONFIG_PROPIO2               /* #define CONFIG_PROPIO2 to enable as tty3 */
 #define PROPIO2_IO_BASE                0xA8
index 7cadb7b..ca43cee 100644 (file)
@@ -5,6 +5,7 @@
 #include <devsys.h>
 #include <devtty.h>
 #include <devide.h>
+#include <devrd.h>
 #include <devsd.h>
 #include <blkdev.h>
 #include <ds1302.h>
@@ -15,7 +16,7 @@ struct devsw dev_tab[] =  /* The device driver switch table */
   {  blkdev_open,   no_close,  blkdev_read,    blkdev_write,   blkdev_ioctl }, /* 0: /dev/hd -- standard block device interface */
   {  no_open,      no_close,   no_rdwr,        no_rdwr,        no_ioctl },     /* 1: unused slot */
   {  tty_open,     tty_close,  tty_read,       tty_write,      tty_ioctl },    /* 2: /dev/tty -- serial ports */
-  {  no_open,      no_close,   no_rdwr,        no_rdwr,        no_ioctl },     /* 3: unused slot */
+  {  rd_open,      no_close,   rd_read,        rd_write,       no_ioctl },     /* 3: /dev/rd? */
   {  no_open,      no_close,   sys_read,       sys_write,      sys_ioctl  },   /* 4: /dev/mem etc      System devices (one offs) */
 };
 
index 5cdf680..49ab4d3 100644 (file)
@@ -5,6 +5,12 @@
 #include "config.h"
 #include <z180.h>
 
+void init_hardware_c(void)
+{
+    ramsize = 512;
+    procmem = 512 - 64 - (DEV_RD_RAM_PAGES<<2);
+}
+
 void pagemap_init(void)
 {
     int i;
@@ -13,7 +19,7 @@ void pagemap_init(void)
      * First 64K is used by the kernel. 
      * Each process gets the full 64K for now.
      * Page size is 4KB. */
-    for(i = 0x90; i < 0x100; i+=0x10)
+    for(i = 0x90; i < ((1024 - (DEV_RD_RAM_PAGES<<2))>>2); i+=0x10)
         pagemap_add(i);
 }
 
index 847a672..951a034 100644 (file)
@@ -36,6 +36,9 @@ platform-n8vem-mark4/discard.rel
 platform-n8vem-mark4/devtty.rel
 platform-n8vem-mark4/devide.rel
 platform-n8vem-mark4/devide_discard.rel
+platform-n8vem-mark4/devrd.rel
+platform-n8vem-mark4/devrd_hw.rel
+platform-n8vem-mark4/devrd_z180_hw.rel
 platform-n8vem-mark4/devsd.rel
 platform-n8vem-mark4/devsd_discard.rel
 platform-n8vem-mark4/devsdspi.rel
index 8fd456f..9f1741d 100644 (file)
@@ -8,7 +8,6 @@ OS_BANK                     .equ 0x00         ; value from include/kernel.h
 
 ; N8VEM Mark IV mnemonics
 FIRST_RAM_BANK              .equ 0x80         ; low 512K of physical memory is ROM/ECB window.
-RAM_KB                      .equ 512
 Z180_IO_BASE                .equ 0x40
 MARK4_IO_BASE               .equ 0x80
 
index 8fe12a1..1b7d0d5 100644 (file)
@@ -14,8 +14,6 @@
         ; imported symbols
         .globl z180_init_hardware
         .globl z180_init_early
-        .globl _ramsize
-        .globl _procmem
         .globl outhl
         .globl outnewline
 
@@ -32,12 +30,6 @@ init_early:
         jp z180_init_early
 
 init_hardware:
-        ; set system RAM size
-        ld hl, #RAM_KB
-        ld (_ramsize), hl
-        ld hl, #(RAM_KB-64)        ; 64K for kernel
-        ld (_procmem), hl
-
         ; enable ASCI interrupts
         in0 a, (ASCI_STAT0)
         or #0x08                ; enable ASCI0 receive interrupts
index 2f9d0ef..305629a 100644 (file)
@@ -4,7 +4,8 @@ DISCARD_CSRCS = discard.c
 DISCARD_DSRCS = ../dev/devide_discard.c ../dev/ds1302_discard.c
 DSRCS = ../dev/blkdev.c ../dev/devide.c ../dev/devfd.c ../dev/mbr.c
 DSRCS += ../dev/ds1302.c
-DASRCS = ../dev/devfd_hw.s
+DSRCS += ../dev/devrd.c
+DASRCS = ../dev/devfd_hw.s ../dev/devrd_hw.s ../dev/devrd_z180_hw.s
 
 AOBJS = $(ASRCS:.s=.rel)
 COBJS = $(CSRCS:.c=.rel)
index b3736b4..cdc050d 100644 (file)
 #define CONFIG_RTC
 #define CONFIG_RTC_INTERVAL 30 /* deciseconds between reading RTC seconds counter */
 
+/* Memory backed devices */
+#define CONFIG_DEV_MEM          /* enable /dev/mem driver */
+#define CONFIG_RAMDISK          /* enable memory-backed device driver */
+#define DEV_RD_ROM_PAGES 0      /* ROM is too small on this platform -- only 32KB */
+#define DEV_RD_RAM_PAGES 0      /* size of the RAM disk (/dev/rd1) in 4KB pages */
+
+#define DEV_RD_ROM_START 0      /* ROM is too small on this platform -- only 32KB */
+#define DEV_RD_ROM_SIZE  0
+#define DEV_RD_RAM_START ((uint32_t)(256-DEV_RD_RAM_PAGES) << 12)
+#define DEV_RD_RAM_SIZE  ((uint32_t)DEV_RD_RAM_PAGES << 12)
+
 /* We have the P112 floppy controller */
 #define CONFIG_P112_FLOPPY
 
index d84acb3..a4d2250 100644 (file)
@@ -7,6 +7,7 @@
 #include <devide.h>
 #include <blkdev.h>
 #include <ds1302.h>
+#include <devrd.h>
 #ifdef CONFIG_P112_FLOPPY
 #include <devfd.h>
 #endif
@@ -21,7 +22,7 @@ struct devsw dev_tab[] =  /* The device driver switch table */
   {  no_open,      no_close,   no_rdwr,        no_rdwr,        no_ioctl },     /* 1: unused slot */
 #endif
   {  tty_open,     tty_close,  tty_read,       tty_write,      tty_ioctl },    /* 2: /dev/tty -- serial ports */
-  {  no_open,      no_close,   no_rdwr,        no_rdwr,        no_ioctl },     /* 3: unused slot */
+  {  rd_open,      no_close,   rd_read,        rd_write,       no_ioctl },     /* 3: /dev/rd?, /dev/physmem -- memory backed devices */
   {  no_open,      no_close,   sys_read,       sys_write,      sys_ioctl  },   /* 4: /dev/mem etc      System devices (one offs) */
 };
 
index fcf2755..8551cbd 100644 (file)
 #include <devide.h>
 #include <ds1302.h>
 
+void init_hardware_c(void)
+{
+    ramsize = 1024;
+    procmem = 1024 - 64 - (DEV_RD_RAM_PAGES<<2);
+}
+
 void pagemap_init(void)
 {
     int i;
@@ -19,9 +25,8 @@ void pagemap_init(void)
      * First 64K is used by the kernel. 
      * Each process gets the full 64K for now.
      * Page size is 4KB. */
-    for(i = 0x10; i < 0x100; i+=0x10){
+    for(i = 0x10; i < ((1024 - (DEV_RD_RAM_PAGES<<2))>>2); i+=0x10)
         pagemap_add(i);
-    }
 }
 
 void map_init(void)
index 0db6241..d5ff7ea 100644 (file)
@@ -36,6 +36,9 @@ platform-p112/discard.rel
 platform-p112/devtty.rel
 platform-p112/devide.rel
 platform-p112/devide_discard.rel
+platform-p112/devrd.rel
+platform-p112/devrd_hw.rel
+platform-p112/devrd_z180_hw.rel
 platform-p112/blkdev.rel
 platform-p112/mbr.rel
 platform-p112/ds1302.rel
index 0fd1bac..bb1368a 100644 (file)
@@ -7,7 +7,6 @@ OS_BANK                     .equ 0x00         ; value from include/kernel.h
 
 ; P112
 FIRST_RAM_BANK              .equ 0x00         ; all memory is RAM on P112
-RAM_KB                      .equ 1024
 Z180_IO_BASE                .equ 0x00
 Z80_TYPE                   .equ 2
 
index 3e22d4a..68cd2ec 100644 (file)
@@ -17,8 +17,6 @@
         ; imported symbols
         .globl z180_init_hardware
         .globl z180_init_early
-        .globl _ramsize
-        .globl _procmem
         .globl outhl
         .globl outnewline
 
@@ -44,12 +42,6 @@ init_early:
         jp z180_init_early
 
 init_hardware:
-        ; set system RAM size
-        ld hl, #RAM_KB
-        ld (_ramsize), hl
-        ld hl, #(RAM_KB-64)        ; 64K for kernel
-        ld (_procmem), hl
-
         ; configure ASCI UART
         ; in0 a, (ASCI_STAT0)
         ; or #0x08                ; enable ASCI0 receive interrupts