Update sramc driver.

This commit is contained in:
Serge Vakulenko
2015-09-29 18:45:48 -07:00
parent 84a38361a5
commit 09112b6b7a
7 changed files with 203 additions and 53 deletions

View File

@@ -35,6 +35,8 @@ dir /u
# 0 11 sd1c Partition 3
# 0 12 sd1d Partition 4
# 1 0 rc0 Volatile disk - SRAM connected via CPLD (sramc)
# 1 1 rc0a Partition 1: filesystem
# 1 2 rc0b Partition 2: swap space
# 2 0 dr0 Volatile disk - SDRAM on external memory bus (sdramp)
# 2 1 dr0a Partition 1: filesystem
# 2 2 dr0b Partition 2: swap space
@@ -78,6 +80,12 @@ minor 12
bdev /dev/rc0
major 1 # Volatile disk - SRAM connected via CPLD (sramc)
minor 0
bdev /dev/rc0a
major 1
minor 1
bdev /dev/rc0b
major 1
minor 2
bdev /dev/dr0
major 2 # Volatile disk - SDRAM on external memory bus (sdramp)
minor 0

View File

@@ -143,11 +143,15 @@ options "SDR_SWAP_KBYTES=2048" # size of partition B
options "KERNEL_EXECUTABLE_RAM" # allow kernel code in RAM area
# sramc - SRAM block device
# The volume is divided into two partitions: A and B.
# Size of partition B is specified as option SRAMC_SWAP_KBYTES.
# The rest is partition A.
device rc0 # SRAM via 4-wire CPLD interface
signal "SRAMC_DATA" pin RE0
signal "SRAMC_LDA" pin RC13
signal "SRAMC_RD" pin RF1
signal "SRAMC_WR" pin RF0
options "SRAMC_SWAP_KBYTES=2048" # size of partition B
# mrams - SPI block device
controller spi1 # RAM disk: mrams

View File

@@ -26,16 +26,16 @@ extern int strcmp(char *s1, char *s2);
#ifdef SD_ENABLED
# include <machine/sd.h>
#endif
#ifdef SRAMC_ENABLED
#ifdef RC_ENABLED
# include <machine/sramc.h>
#endif
#ifdef SDRAMP_ENABLED
#ifdef DR_ENABLED
# include <machine/sdramp.h>
#endif
#ifdef MRAMS_ENABLED
#ifdef MR_ENABLED
# include <machine/mrams.h>
#endif
#ifdef SPIRAMS_ENABLED
#ifdef SR_ENABLED
# include <machine/spirams.h>
#endif
#ifdef UARTUSB_ENABLED
@@ -124,7 +124,7 @@ const struct bdevsw bdevsw[] = {
#endif
},
{ /* 1 - sramc */
#ifdef SRAMC_ENABLED
#ifdef RC_ENABLED
sramc_open, sramc_close, sramc_strategy,
sramc_size, sramc_ioctl,
#else
@@ -132,7 +132,7 @@ const struct bdevsw bdevsw[] = {
#endif
},
{ /* 2 - sdramp */
#ifdef SDRAMP_ENABLED
#ifdef DR_ENABLED
sdramp_open, sdramp_close, sdramp_strategy,
sdramp_size, sdramp_ioctl,
#else
@@ -140,7 +140,7 @@ const struct bdevsw bdevsw[] = {
#endif
},
{ /* 3 - mrams */
#ifdef MRAMS_ENABLED
#ifdef MR_ENABLED
mrams_open, mrams_close, mrams_strategy,
mrams_size, mrams_ioctl,
#else
@@ -152,7 +152,7 @@ const struct bdevsw bdevsw[] = {
swsize, swcioctl,
},
{ /* 5 - spirams */
#ifdef SPIRAMS_ENABLED
#ifdef SR_ENABLED
spirams_open, spirams_close, spirams_strategy,
spirams_size, spirams_ioctl,
#else

View File

@@ -33,7 +33,7 @@ signal "LED_KERNEL" pin RE5 # kernel activity indicator
# Root filesystem at /dev/sd0a, swap at /dev/sd0b
config unix root on sd0a
swap on sd0b
swap on rc0b # Swap on SRAM disk
# Console options
options "CONS_MAJOR=UART_MAJOR" # UART device
@@ -70,5 +70,8 @@ device adc
device pwm
# sramc - SRAM block device
device sramc0 # SRAM via 4-wire CPLD interface
options "PARTITION='sramc0:sa@2048,fs@6140'" # Partition schema
# The volume is divided into two partitions: A and B.
# Size of partition B is specified as option SRAMC_SWAP_KBYTES.
# The rest is partition A.
device rc0 # SRAM via 4-wire CPLD interface
options "SRAMC_SWAP_KBYTES=2048" # size of partition B

View File

@@ -460,7 +460,7 @@ void sdramp_strategy(struct buf *bp)
splx(s);
}
int sdramp_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag)
int sdramp_ioctl(dev_t dev, u_int cmd, caddr_t addr, int flag)
{
int error = 0;

View File

@@ -22,10 +22,18 @@
#include <sys/buf.h>
#include <sys/errno.h>
#include <sys/dk.h>
#include <sys/debug.h>
#include <sys/ioctl.h>
#include <sys/disk.h>
#include <sys/kconfig.h>
#include <machine/debug.h>
#include <machine/sramc.h>
int sw_dkn = -1; /* Statistics slot number */
int sramc_dkindex = -1; /* Statistics slot number */
/*
* Size of RAM disk.
*/
#define SRAMC_TOTAL_KBYTES 8192 /* 4096 for 4MB ramdisk */
// Ramdisk v.1.1. wiring
// PMP RAMDISK
@@ -77,13 +85,13 @@ typedef union {
*
*/
inline static void
dev_load_address (addr)
dev_load_address(addr)
unsigned addr;
{
nybbles temp;
temp.value = addr;
while(PMMODE & 0x8000); // Poll - if busy, wait
while (PMMODE & 0x8000); // Poll - if busy, wait
PMADDR = 1; // set ADR mode (1) to write the Address
@@ -91,45 +99,58 @@ dev_load_address (addr)
PMDIN = temp.nib6; /* write 4 bits */
while(PMMODE & 0x8000); // Poll - if busy, wait
while (PMMODE & 0x8000); // Poll - if busy, wait
PMDIN = temp.nib5; /* write 4 bits */
while(PMMODE & 0x8000); // Poll - if busy, wait
while (PMMODE & 0x8000); // Poll - if busy, wait
PMDIN = temp.nib4; /* write 4 bits */
while(PMMODE & 0x8000); // Poll - if busy, wait
while (PMMODE & 0x8000); // Poll - if busy, wait
PMDIN = temp.nib3; /* write 4 bits */
while(PMMODE & 0x8000); // Poll - if busy, wait
while (PMMODE & 0x8000); // Poll - if busy, wait
PMDIN = temp.nib2; /* write 4 bits */
while(PMMODE & 0x8000); // Poll - if busy, wait
while (PMMODE & 0x8000); // Poll - if busy, wait
PMDIN = temp.nib1; /* write 4 bits */
}
/*
* Get number of kBytes on the disk.
* Return nonzero if successful.
* Return a size of partition in kbytes.
* The memory is divided into two partitions: A and B.
* Size of partition B is specified in the kernel config file
* as option SRAMC_SWAP_KBYTES.
*/
int sramc_size ( int unit )
daddr_t sramc_size(dev_t dev)
{
return 8192; // 4096 for 4MB ramdisk
switch (minor(dev)) {
case 0:
/* Whole disk. */
return SRAMC_TOTAL_KBYTES;
case 1:
/* Partition A: filesystem. */
return SRAMC_TOTAL_KBYTES - SRAMC_SWAP_KBYTES;
case 2:
default:
/* Partition B: swap space. */
return SRAMC_SWAP_KBYTES;
}
}
/*
* Read a block of data.
*/
inline int sramc_read (int unit, unsigned int blockno, char *data, unsigned int nbytes)
static int sramc_read(unsigned int blockno, char *data, unsigned int nbytes)
{
int i;
//DEBUG9("sramc%d: read block %u, length %u bytes, addr %p\n", major(dev), blockno, nbytes, data);
dev_load_address (blockno * DEV_BSIZE);
dev_load_address(blockno * DEV_BSIZE);
/* Read data. */
while(PMMODE & 0x8000); // Poll - if busy, wait
while (PMMODE & 0x8000); // Poll - if busy, wait
PMADDR = 0; // set DATA mode (0)
@@ -138,7 +159,7 @@ inline int sramc_read (int unit, unsigned int blockno, char *data, unsigned int
PMDIN; // Read the PMDIN to clear previous data and latch new data
for (i=0; i<nbytes; i++) {
while(PMMODE & 0x8000); // Poll - if busy, wait before reading
while (PMMODE & 0x8000); // Poll - if busy, wait before reading
*data++ = PMDIN; /* read a byte of data */
}
return 1;
@@ -147,13 +168,13 @@ inline int sramc_read (int unit, unsigned int blockno, char *data, unsigned int
/*
* Write a block of data.
*/
inline int sramc_write (int unit, unsigned int blockno, char *data, unsigned int nbytes)
static int sramc_write(unsigned int blockno, char *data, unsigned int nbytes)
{
unsigned i;
//DEBUG9("sramc%d: write block %u, length %u bytes, addr %p\n", major(dev), blockno, nbytes, data);
dev_load_address (blockno * DEV_BSIZE);
dev_load_address(blockno * DEV_BSIZE);
/* Write data. */
@@ -164,8 +185,8 @@ inline int sramc_write (int unit, unsigned int blockno, char *data, unsigned int
PMMODE = 0b10<<8 | (WR_PULSE<<2); // faster with write
for (i=0; i<nbytes; i++) {
while(PMMODE & 0x8000); // Poll - if busy, wait
PMDIN = (*data++); /* write a byte of data */
while (PMMODE & 0x8000); // Poll - if busy, wait
PMDIN = *data++; /* write a byte of data */
}
return 1;
}
@@ -173,10 +194,8 @@ inline int sramc_write (int unit, unsigned int blockno, char *data, unsigned int
/*
* Init the disk.
*/
void sramc_init (int unit)
static void sramc_init()
{
struct buf *bp;
// Initialize PMP hardware
PMCON = 0; // disable PMP
@@ -195,26 +214,144 @@ void sramc_init (int unit)
asm volatile ("nop");
// make a couple of dummy reads - it refreshes the cpld internals a little bit :)
while(PMMODE & 0x8000); // Poll - if busy, wait before reading
while (PMMODE & 0x8000); // Poll - if busy, wait before reading
PMDIN; /* read a byte of data */
while(PMMODE & 0x8000); // Poll - if busy, wait before reading
while (PMMODE & 0x8000); // Poll - if busy, wait before reading
PMDIN; /* read a byte of data */
PMADDR = 1; // go with with ADDRESS mode now
DEBUG3("sramc%d: init done\n",unit);
bp = prepartition_device("sramc0");
if (bp) {
sramc_write(0, 0, bp->b_addr, 512);
brelse(bp);
}
DEBUG3("sramc: init done\n");
}
/*
* Open the disk.
*/
int sramc_open (int unit)
int sramc_open(dev_t dev, int flag, int mode)
{
DEBUG3("sramc%d: open\n",unit);
DEBUG3("sramc: open\n");
return 0;
}
int sramc_close(dev_t dev, int flag, int mode)
{
return 0;
}
void sramc_strategy(struct buf *bp)
{
int offset = bp->b_blkno;
long nblk = btod(bp->b_bcount);
int part_offset, part_size, s;
/* Compute partition size and offset. */
part_size = sramc_size(bp->b_dev);
if (minor(bp->b_dev) < 2) {
/* Partition A or a whole disk. */
part_offset = 0;
} else {
/* Partition B: swap space. */
part_offset = SRAMC_TOTAL_KBYTES - part_size;
}
/*
* Determine the size of the transfer, and make sure it is
* within the boundaries of the partition.
*/
offset += part_offset;
if (bp->b_blkno + nblk > part_size) {
/* if exactly at end of partition, return an EOF */
if (bp->b_blkno == part_size) {
bp->b_resid = bp->b_bcount;
biodone(bp);
return;
}
/* or truncate if part of it fits */
nblk = part_size - bp->b_blkno;
if (nblk <= 0) {
bp->b_error = EINVAL;
bp->b_flags |= B_ERROR;
biodone(bp);
return;
}
bp->b_bcount = nblk << DEV_BSHIFT;
}
if (bp->b_dev == swapdev) {
led_control(LED_SWAP, 1);
} else {
led_control(LED_DISK, 1);
}
s = splbio();
#ifdef UCB_METER
if (sramc_dkindex >= 0) {
dk_busy |= 1 << sramc_dkindex;
dk_xfer[sramc_dkindex]++;
dk_bytes[sramc_dkindex] += bp->b_bcount;
}
#endif
if (bp->b_flags & B_READ) {
sramc_read(offset, bp->b_addr, bp->b_bcount);
} else {
sramc_write(offset, bp->b_addr, bp->b_bcount);
}
biodone(bp);
if (bp->b_dev == swapdev) {
led_control(LED_SWAP, 0);
} else {
led_control(LED_DISK, 0);
}
#ifdef UCB_METER
if (sramc_dkindex >= 0)
dk_busy &= ~(1 << sramc_dkindex);
#endif
splx(s);
}
int sramc_ioctl(dev_t dev, u_int cmd, caddr_t addr, int flag)
{
int error = 0;
switch (cmd) {
case DIOCGETMEDIASIZE:
/* Get disk size in kbytes. */
*(int*) addr = sramc_size(dev);
break;
default:
error = EINVAL;
break;
}
return error;
}
/*
* Test to see if device is present.
* Return true if found and initialized ok.
*/
static int
sramcprobe(config)
struct conf_device *config;
{
/* Only one device unit is supported. */
if (config->dev_unit != 0)
return 0;
printf("rc0: total %u kbytes, swap space %u kbytes\n",
SRAMC_TOTAL_KBYTES, SRAMC_SWAP_KBYTES);
sramc_init();
#ifdef UCB_METER
dk_alloc(&sramc_dkindex, 1, "rc0");
#endif
return 1;
}
struct driver rcdriver = {
"sramc", sramcprobe,
};

View File

@@ -2,13 +2,11 @@
#define _SRAMC_H
#ifdef KERNEL
extern int sramc_read(int unit, unsigned int offset, char *data, unsigned int bcount);
extern int sramc_write(int unit, unsigned int offset, char *data, unsigned int bcount);
extern int sramc_open(int unit, int flag, int mode);
extern void sramc_init(int unit);
extern int sramc_size(int unit);
extern int sramc_open(dev_t dev, int flag, int mode);
extern int sramc_close(dev_t dev, int flag, int mode);
extern daddr_t sramc_size(dev_t dev);
extern void sramc_strategy(struct buf *bp);
extern int sramc_ioctl (dev_t dev, u_int cmd, caddr_t addr, int flag);
#endif
#endif