Mercurial > sos > sos
changeset 34:720e29b26c81
merge
author | Jonathan Pevarnek <pevarnj@gmail.com> |
---|---|
date | Wed, 06 Apr 2011 17:18:00 -0400 |
parents | fc797d0cb298 (current diff) e984f53304ea (diff) |
children | f806eec33c45 |
files | arch/io.c hercules/dynamic.cnf hercules/sarpn.cnf include/system.h |
diffstat | 5 files changed, 219 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/arch/io.c Mon Apr 04 14:48:10 2011 -0400 +++ b/arch/io.c Wed Apr 06 17:18:00 2011 -0400 @@ -414,9 +414,8 @@ for(;;); \ } while(0) -static void enable_cons(int devnum) +u32 find_dev(int devnum) { - struct psw psw; struct schib schib; u32 sch; @@ -435,53 +434,64 @@ if (modify_sch(sch, &schib)) continue; - // found it - init_cons = 1; - consch = sch; - - // set up the IO interrupt handler - psw.ea = 1; - psw.ba = 1; - - asm volatile( - " larl %%r1,0f\n" - " stg %%r1,%0\n" - " brc 15,1f\n" - /* IO handler code begins */ - "0:\n" - " l %%r1,0xb8\n" - " larl %%r2,irb\n" - " tsch 0(%%r2)\n" - " l %%r1,5(%%r2)\n" - " nill %%r1,0x04\n" - " brc 8,2f\n" // done? - " lg %%r1,0x178\n" // yes. - " bcr 15,%%r1\n" - "2:\n" - " l %%r1,5(%%r2)\n" - " nill %%r1,0x80\n" - " brc 8,3f\n" // attention? - " lg %%r1,0x178\n" // yes. - " bcr 15,%%r1\n" - "3:\n" - " lpswe 0x170\n" - /* IO handler code ends */ - "1:\n" - : /* output */ - "=m" (psw.ptr), - "=m" (irb) - : /* input */ - "a" (&irb) - : /* clobbered */ - "r1", "r2" - ); - - __builtin_memcpy(((void*) 0x1f0), &psw, sizeof(struct psw)); - - return; + return sch; } - die(); + return 0; +} + +static void enable_cons(int devnum) +{ + struct psw psw; + u32 sch; + + sch = find_dev(devnum); + + if (!sch) + die(); + + // found it + init_cons = 1; + consch = sch; + + // set up the IO interrupt handler + psw.ea = 1; + psw.ba = 1; + + asm volatile( + " larl %%r1,0f\n" + " stg %%r1,%0\n" + " brc 15,1f\n" + /* IO handler code begins */ + "0:\n" + " l %%r1,0xb8\n" + " larl %%r2,irb\n" + " tsch 0(%%r2)\n" + " l %%r1,5(%%r2)\n" + " nill %%r1,0x04\n" + " brc 8,2f\n" // done? + " lg %%r1,0x178\n" // yes. + " bcr 15,%%r1\n" + "2:\n" + " l %%r1,5(%%r2)\n" + " nill %%r1,0x80\n" + " brc 8,3f\n" // attention? + " lg %%r1,0x178\n" // yes. + " bcr 15,%%r1\n" + "3:\n" + " lpswe 0x170\n" + /* IO handler code ends */ + "1:\n" + : /* output */ + "=m" (psw.ptr), + "=m" (irb) + : /* input */ + "a" (&irb) + : /* clobbered */ + "r1", "r2" + ); + + __builtin_memcpy(((void*) 0x1f0), &psw, sizeof(struct psw)); } static inline void wait_for_io_int() @@ -576,3 +586,156 @@ return i; } + +#define FBA_BLK_SIZE 512 + +#define DASD_FBA_WRITE 0x41 +#define DASD_FBA_READ 0x42 +#define DASD_FBA_LOCATE_RECORD 0x43 +#define DASD_FBA_DEFINE_EXTENT 0x63 + +enum op_type { + WRITE = 0, + READ, +}; + +struct fba_DE_data { + u8 perm:2, /* Permissions on this extent */ + __zero0:2, + da:1, + diag:1, /* allow diagnose */ + __zero1:2; + u8 __zero3; + u16 blksize; /* Blocksize */ + u32 ext_loc; /* Extent locator */ + u32 ext_beg; /* logical number of block 0 in extent */ + u32 ext_end; /* logocal number of last block in extent */ +}; + +struct fba_LO_data { + u8 zero:4, + cmd:4; + u8 aux; + u16 count; + u32 blkno; +}; + +/* build a Define-Extent CCW */ +static void fba_define_extent(struct ccw *ccw, struct fba_DE_data *data, + enum op_type rw, u16 blksize, u32 blkno, u32 len) +{ + ccw->cmd = DASD_FBA_DEFINE_EXTENT; + ccw->count = 0x10; + ccw->addr = (u32) (u64) data; + + __builtin_memset(data, 0, sizeof(struct fba_DE_data)); + switch(rw) { + case WRITE: + data->perm = 0x00; + break; + case READ: + data->perm = 0x01; + break; + default: + die(); + break; + } + data->blksize = blksize; + data->ext_loc = blkno; + data->ext_end = len - 1; +} + +/* build a Locate-Record CCW */ +static void fba_locate_record(struct ccw *ccw, struct fba_LO_data *data, + enum op_type rw, u32 blkno, u32 len) +{ + ccw->cmd = DASD_FBA_LOCATE_RECORD; + ccw->count = 0x08; + ccw->addr = (u32) (u64) data; + + __builtin_memset(data, 0, sizeof(struct fba_LO_data)); + switch(rw) { + case WRITE: + data->cmd = 0x05; + break; + case READ: + data->cmd = 0x06; + break; + default: + die(); + break; + } + data->blkno = blkno; + data->count = len; +} + +/* build a Read or Write CCW */ +static void fba_readwrite(struct ccw *ccw, void *ptr, enum op_type rw, u32 len) +{ + if(len > 0xffff) + die(); + + switch(rw) { + case 0: + ccw->cmd = DASD_FBA_WRITE; + break; + case 1: + ccw->cmd = DASD_FBA_READ; + break; + default: + die(); + break; + } + + ccw->count = len; + ccw->addr = (u32) (u64) ptr; +} + +/** + * fba_read_blk - read a block from an FBA device + * @dev: device to read from + * @blkno: block number to read + * @ptr: buffer to fill + * @sync: synchronous I/O + */ +static int __fba_readwrite_blk(u32 dev, u32 blkno, void *ptr, enum op_type dir) +{ + struct ccw ccw[3]; + struct fba_DE_data defext; + struct fba_LO_data locate; + + __builtin_memset(&orb, 0, sizeof(struct orb)); + orb.lpm = 0xff; + orb.addr = (u32) (u64) ccw; + orb.f = 1; + + __builtin_memset(ccw, 0, sizeof(ccw)); + + /* Define-Extent */ + fba_define_extent(&ccw[0], &defext, dir, FBA_BLK_SIZE, blkno, 1); + ccw[0].flags |= 0x40; + + /* Locate */ + fba_locate_record(&ccw[1], &locate, dir, 0, 1); + ccw[1].flags |= 0x40; + + /* Read */ + fba_readwrite(&ccw[2], ptr, dir, FBA_BLK_SIZE); + + if (start_sch(dev, &orb)) + die(); + + wait_for_io_int(); + + return 0; +} + +int fba_read_blk(u32 dev, u32 blkno, void *ptr) +{ + return __fba_readwrite_blk(dev, blkno, ptr, READ); +} + +int fba_write_blk(u32 dev, u32 blkno, void *ptr) +{ + return __fba_readwrite_blk(dev, blkno, ptr, WRITE); +}
--- a/hercules/dynamic.cnf Mon Apr 04 14:48:10 2011 -0400 +++ b/hercules/dynamic.cnf Wed Apr 06 17:18:00 2011 -0400 @@ -16,3 +16,5 @@ #--- ---- -------------------- 0009 3215 000C 3505 ../loader.bin ../dynamic ebcdic multifile eof + +0100 9336 disk.img
--- a/hercules/sarpn.cnf Mon Apr 04 14:48:10 2011 -0400 +++ b/hercules/sarpn.cnf Wed Apr 06 17:18:00 2011 -0400 @@ -16,3 +16,5 @@ #--- ---- -------------------- 0009 3215 000C 3505 ../loader.bin ../sarpn ebcdic multifile eof + +0100 9336 disk.img
--- a/include/system.h Mon Apr 04 14:48:10 2011 -0400 +++ b/include/system.h Wed Apr 06 17:18:00 2011 -0400 @@ -29,6 +29,11 @@ extern int putline(char *buf, int len); extern int getline(char *buf, int len); + extern u32 find_dev(int devnum); + + extern int fba_read_blk(u32 dev, u32 blkno, void *ptr); + extern int fba_write_blk(u32 dev, u32 blkno, void *ptr); + #ifdef __cplusplus } #endif