Index: AplioTRIO/linux/arch/armnommu/Makefile diff -c AplioTRIO/linux/arch/armnommu/Makefile:1.2 AplioTRIO/linux/arch/armnommu/Makefile:1.4 *** AplioTRIO/linux/arch/armnommu/Makefile:1.2 Tue Nov 23 15:21:43 1999 --- AplioTRIO/linux/arch/armnommu/Makefile Wed Jan 12 17:24:38 2000 *************** *** 46,52 **** ifeq ($(CONFIG_CPU_ARM7),y) PROCESSOR = armv ifeq ($(CONFIG_BINUTILS_NEW),y) ! CFLAGS_PROC += -mcpu=arm7 -fno-strict-aliasing else CFLAGS_PROC += -m6 endif --- 46,52 ---- ifeq ($(CONFIG_CPU_ARM7),y) PROCESSOR = armv ifeq ($(CONFIG_BINUTILS_NEW),y) ! CFLAGS_PROC += -mcpu=arm7tdmi -fno-strict-aliasing else CFLAGS_PROC += -m6 endif *************** *** 101,114 **** ifeq ($(PROCESSOR),armv) ifeq ($(CONFIG_BINUTILS_NEW),y) ! CFLAGS_PROC += -mapcs-32 -mshort-load-bytes endif TEXTADDR = 0xC0008000 endif ifeq ($(CONFIG_ARCH_TRIO),y) MACHINE = trio ! TEXTADDR = 0x1000 endif ifeq ($(CONFIG_ARCH_RPC),y) --- 101,115 ---- ifeq ($(PROCESSOR),armv) ifeq ($(CONFIG_BINUTILS_NEW),y) ! #CFLAGS_PROC += -mapcs-32 -mshort-load-bytes ! CFLAGS_PROC += -mapcs-32 endif TEXTADDR = 0xC0008000 endif ifeq ($(CONFIG_ARCH_TRIO),y) MACHINE = trio ! TEXTADDR = 0x2000 endif ifeq ($(CONFIG_ARCH_RPC),y) Index: AplioTRIO/linux/arch/armnommu/config.in diff -c AplioTRIO/linux/arch/armnommu/config.in:1.2 AplioTRIO/linux/arch/armnommu/config.in:1.4 *** AplioTRIO/linux/arch/armnommu/config.in:1.2 Mon Nov 15 15:38:50 1999 --- AplioTRIO/linux/arch/armnommu/config.in Fri Jan 28 16:19:57 2000 *************** *** 64,70 **** --- 64,79 ---- bool 'System V IPC' CONFIG_SYSVIPC #tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT #tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF + define_bool CONFIG_BINFMT_FLAT y define_bool CONFIG_KERNEL_ELF y + + bool 'Console support' CONFIG_CONSOLE + if [ "$CONFIG_CONSOLE" = "y" ]; then + bool 'Frame buffer' CONFIG_FRAMEBUFFER + if [ "$CONFIG_PILOT" = "y" -a "$CONFIG_FRAMEBUFFER" = "y" ]; then + bool 'Pilot console' CONFIG_PILOT_CONSOLE + fi + fi if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then # tristate 'Kernel support for JAVA binaries' CONFIG_BINFMT_JAVA Index: AplioTRIO/linux/arch/armnommu/drivers/block/Config.in diff -c AplioTRIO/linux/arch/armnommu/drivers/block/Config.in:1.1.1.1 AplioTRIO/linux/arch/armnommu/drivers/block/Config.in:1.2 *** AplioTRIO/linux/arch/armnommu/drivers/block/Config.in:1.1.1.1 Mon Nov 15 14:42:35 1999 --- AplioTRIO/linux/arch/armnommu/drivers/block/Config.in Mon Dec 27 20:21:05 1999 *************** *** 37,44 **** --- 37,46 ---- fi tristate 'RAM disk support' CONFIG_BLK_DEV_RAM if [ "$CONFIG_BLK_DEV_RAM" = "y" ]; then + bool ' Release empty RAM disk blocks' CONFIG_RD_RELEASE_BLOCKS bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD fi + tristate 'ROM disk memory block device' CONFIG_BLK_DEV_BLKMEM bool 'ADFS partition support' CONFIG_BLK_DEV_PART #if [ "$CONFIG_BLK_DEV_PART" = "y" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then # bool 'ADFS image file support (EXPERIMENTAL)' CONFIG_BLK_DEV_IMG Index: AplioTRIO/linux/arch/armnommu/drivers/block/Makefile diff -c AplioTRIO/linux/arch/armnommu/drivers/block/Makefile:1.1.1.1 AplioTRIO/linux/arch/armnommu/drivers/block/Makefile:1.2 *** AplioTRIO/linux/arch/armnommu/drivers/block/Makefile:1.1.1.1 Mon Nov 15 14:42:35 1999 --- AplioTRIO/linux/arch/armnommu/drivers/block/Makefile Mon Dec 27 20:21:06 1999 *************** *** 61,66 **** --- 61,75 ---- endif endif + ifeq ($(CONFIG_BLK_DEV_BLKMEM),y) + L_OBJS += blkmem.o + else + ifeq ($(CONFIG_BLK_DEV_RAM),m) + M_OBJS += blkmem.o + endif + endif + + ifeq ($(CONFIG_BLK_DEV_LOOP),y) L_OBJS += loop.o else *************** *** 147,152 **** --- 156,162 ---- M_OBJS += raid5.o endif endif + endif Index: AplioTRIO/linux/arch/armnommu/drivers/block/blkmem.c diff -c /dev/null AplioTRIO/linux/arch/armnommu/drivers/block/blkmem.c:1.1 *** /dev/null Fri Jan 28 16:54:03 2000 --- AplioTRIO/linux/arch/armnommu/drivers/block/blkmem.c Mon Dec 27 20:21:06 1999 *************** *** 0 **** --- 1,1186 ---- + /* blkmem.c: Block access to memory spaces + * + * Copyright (C) 1997, 1998 D. Jeff Dionne , + * Kenneth Albanowski , + * The Silver Hammer Group, Ltd. + * + * Based z2ram - Amiga pseudo-driver to access 16bit-RAM in ZorroII space + * Copyright (C) 1994 by Ingo Wilken (Ingo.Wilken@informatik.uni-oldenburg.de) + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose and without fee is hereby granted, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation. This software is provided "as is" without express or + * implied warranty. + */ + + + + #include + #include + #include + + #define MAJOR_NR BLKMEM_MAJOR + + #undef VERBOSE + #undef DEBUG + + #include + + #include + + #if 0 + #include + #endif + + #if defined(MODULE) + #include + #endif + + #include + #include + + #define TRUE (1) + #define FALSE (0) + + #if defined( CONFIG_M68328 ) || defined ( CONFIG_M68EZ328 ) + #include + + #define CAT_ROMARRAY + #endif + + #ifdef CONFIG_ARCH_TRIO + #define FIXED_ROMARRAY (char*)(3512*1024) + #endif + + + /* Simple romfs, at internal, cat on the end of kernel, or seperate fixed adderess romfs. */ + + #ifdef INTERNAL_ROMARRAY + #include "testromfs.c" + #endif + + #ifdef CAT_ROMARRAY + unsigned char *romarray; + extern char __data_rom_start[]; + extern char _edata[]; + extern char __data_start[]; + #endif + + #ifdef FIXED_ROMARRAY + unsigned char *romarray = (char *)(FIXED_ROMARRAY); + #endif + + /* If defined, ROOT_ARENA causes the root device to be the specified arena, useful with romfs */ + + /* Now defining ROOT_DEV in arch/setup.c */ + /*#define ROOT_ARENA 0*/ + + struct arena_t; + + typedef void (*xfer_func_t)(struct arena_t *, unsigned long address, unsigned long length, char * buffer); + typedef void (*erase_func_t)(struct arena_t *, unsigned long address); + typedef void (*program_func_t)(struct arena_t *, struct blkmem_program_t * prog); + + void program_main(struct arena_t *, struct blkmem_program_t *); + void read_spare(struct arena_t *, unsigned long, unsigned long, char *); + void write_spare(struct arena_t *, unsigned long, unsigned long, char *); + void erase_spare(struct arena_t *, unsigned long); + + + /* This array of structures defines the actual set of memory arenas, including + access functions (if the memory isn't part of the main address space) */ + + struct arena_t { + int rw; + + unsigned long address; /* Address of memory arena */ + unsigned long length; /* Length of memory arena. If -1, try to get size from romfs header */ + + program_func_t program_func; /* Function to program in one go */ + + xfer_func_t read_func; /* Function to transfer data to main memory, or zero if none needed */ + xfer_func_t write_func; /* Function to transfer data from main memory, zero if none needed */ + + erase_func_t erase_func; /* Function to erase a block of memory to zeros, or 0 if N/A */ + unsigned long blksize; /* Size of block that can be erased at one time, or 0 if N/A */ + unsigned long unitsize; + unsigned char erasevalue; /* Contents of sectors when erased */ + + /*unsigned int auto_erase_bits; + unsigned int did_erase_bits;*/ + + } arena[] = { + + #ifdef INTERNAL_ROMARRAY + {romarray, sizeof(romarray)}, + #endif + + #ifdef CAT_ROMARRAY + {0, 0, -1}, + #define FIXUP_ARENAS \ + arena[0].address = (unsigned long)__data_rom_start + (unsigned long)_edata - (unsigned long)__data_start; + #endif + + #ifdef FIXED_ROMARRAY + {0, FIXED_ROMARRAY, -1} + #endif + + #ifdef CONFIG_SHGLCORE + + #ifdef CONFIG_SHGLCORE_2MEG + {0, 0x0A0000, 0x200000-0x0A0000}, /* ROM FS */ + {1, SHGLCORE_FLASH_BANK_0_ADDR, 0x80000, 0, 0, write_spare, erase_spare, 0x10000, 0x80000, 0xff}, + {1, 0x000000, 0x200000, program_main, 0,0,0, 0x20000, 0x100000}, /* All main FLASH */ + #else + {0, 0x0A0000, 0x100000-0x0A0000}, /* ROM FS */ + {1, SHGLCORE_FLASH_BANK_0_ADDR, 0x80000, 0, 0, write_spare, erase_spare, 0x10000, 0x80000, 0xff}, + {1, 0x000000, 0x100000, program_main, 0,0,0, 0x20000, 0x100000}, /* All main FLASH */ + #endif + + #define FIXUP_ARENAS \ + extern unsigned long rom_length; \ + arena[0].length = (unsigned long)rom_length - 0xA0000; \ + arena[2].length = (unsigned long)rom_length; + + #endif + + }; + + #define arenas (sizeof(arena) / sizeof(struct arena_t)) + + + static int blkmem_blocksizes[arenas]; + static int blkmem_sizes[arenas]; + + + #ifdef CONFIG_SHGLCORE + static struct semaphore spare_lock = MUTEX; + + void read_spare(struct arena_t * a, unsigned long pos, unsigned long length, char * buffer) + { + + #ifdef DEBUG + printk("rsl\n"); + #endif + + /* Mutex all access to FLASH */ + down(&spare_lock); + + #ifdef DEBUG + printk("rsld\n"); + #endif + + /* Just copy the data into target buffer */ + memcpy( buffer, (void*)(a->address+pos), length); + + /* Release MUTEX */ + up(&spare_lock); + + #ifdef DEBUG + printk("rsud\n"); + #endif + } + + void write_spare(struct arena_t * a, unsigned long pos, unsigned long length, char * buffer) + { + unsigned long start; + unsigned char c; + volatile unsigned char * address; + unsigned char result; + unsigned long fbase = a->address; + unsigned long flags; + + #if 0 + for(i = pos / a->blksize; i <= ((pos+length-1) / a->blksize); i++) { + if (test_bit(i, &a->auto_erase_bits)) { + /* erase sector start */ + printk("Autoerase of sector %d\n", i); + erase_spare(a, i * a->blksize); + clear_bit(i, &a->auto_erase_bits); + } + } + #endif + + #ifdef DEBUG + printk("wsl\n"); + #endif + + down(&spare_lock); + + #ifdef DEBUG + printk("wsld\n"); + #endif + + start = jiffies; + + address = (unsigned volatile char*)(fbase+pos); + + while (length>0) { + + c = *buffer++; + + /*printk("Checking spare_flash program of byte %lx, at address %p, value %x (%c), current %x (%c)\n", pos, address, c, c, *address, *address);*/ + + if (*address != c) { + + /*printk("Starting spare_flash program of byte %lx, at address %p\n", pos, address);*/ + + + if (c & ~*address) { + printk("Unable to write byte at %p (impossible bit transition in %x, actual %x)\n", address, c, *address); + /*continue;*/ + } + + save_flags(flags); cli(); + + *(unsigned volatile char *)(fbase | 0x5555)=0x0aa; + *(unsigned volatile char *)(fbase | 0x2aaa)=0x055; + *(unsigned volatile char *)(fbase | 0x5555)=0x0a0; + + *address = c; + + for(;;) { + result = *address; + /*printk("Read value %x (%c)\n", result, result);*/ + if ((result & 0x80) == (c & 0x80)) + break; + if (result & 0x20) { + printk("timeout of FLASH write at address %p of value %x (actual %x)\n", address, c, *address); + *(unsigned volatile char *)(fbase)=0x0f0; /* Reset */ + break; + } + } + + restore_flags(flags); + + /*printk("Completed spare_flash program of byte %lx, at address %p\n", pos, address);*/ + + #if 0 + if (jiffies != start) { + /*printk("Spare_flash rescheduling in write\n");*/ + current->state = TASK_INTERRUPTIBLE; + current->timeout = jiffies; + schedule(); + current->timeout = 0; + /*schedule();*/ + start = jiffies; + } + #endif + } + + address++; + length--; + } + + up(&spare_lock); + + #ifdef DEBUG + printk("wsud\n"); + #endif + } + + void erase_spare(struct arena_t * a, unsigned long pos) + { + unsigned long fbase = a->address; + int delay; + unsigned volatile char * address; + unsigned long flags; + + if (pos >= a->length) + return; + + /* Mutex all access to FLASH memory */ + + #ifdef DEBUG + printk("esl\n"); + #endif + + down(&spare_lock); + + #ifdef DEBUG + printk("esld\n"); + #endif + + address = (unsigned volatile char*)(fbase + pos); + + printk("Starting spare_flash erase of byte %lx, at address %p\n", pos, address); + + save_flags(flags); cli(); + + again: + + delay = HZ/4+1; + + /* Initiate erase of FLASH sector */ + + *(unsigned volatile char *)(fbase | 0x5555)=0x0aa; + *(unsigned volatile char *)(fbase | 0x2aaa)=0x055; + *(unsigned volatile char *)(fbase | 0x5555)=0x080; + *(unsigned volatile char *)(fbase | 0x5555)=0x0aa; + *(unsigned volatile char *)(fbase | 0x2aaa)=0x055; + + *address = 0x030; + + /* Delay until erase is complete */ + + for (;;) { + unsigned char result; + #ifdef original_spare_erase_delay + struct wait_queue *wait = NULL; + #ifdef DEBUG + printk("Spare_flash erase delaying for %d ticks, status is %x\n", delay, (unsigned int)*address); + #endif + + current->timeout = jiffies + delay; + #if 0 + current->state = TASK_INTERRUPTIBLE; + schedule(); + current->timeout = 0; + #endif + interruptible_sleep_on(&wait); + #endif + udelay(100000); + + result = *address; + if (result & 0x80) + break; + if (result & 0x20) { + printk("timeout of Spare_flash erase of address %p\n", address); + *(unsigned volatile char *)(fbase)=0x0f0; /* Reset */ + printk("Sleeping a second and retrying\n"); + + udelay(1000000); + + goto again; + } + } + + restore_flags(flags); + + #ifdef DEBUG + printk("Completed spare_flash erase of byte %lx, at address %p\n", pos, address); + #endif + + up(&spare_lock); + + #ifdef DEBUG + printk("esud\n"); + #endif + + } + + #define VSP(X) (*(volatile unsigned short *)(X)) + #define VSC(X) (*(volatile unsigned char *)(X)) + + #define SCSR VSP(0xfffc0c) + #define SCSR_TDRE (1<<8) + + #define SCDR VSP(0xfffC0e) + + #define print_char(x) ({ \ + while (!(SCSR & SCSR_TDRE)) \ + ; \ + SCDR = (x); \ + }) + + #define print_hexdigit(x) ({ \ + int digit = (x) & 0xf; \ + if (digit>9) \ + print_char('a'+digit-10); \ + else \ + print_char('0'+digit); \ + \ + }) + + #define print_num(x) ({ \ + unsigned long num = (x); \ + print_hexdigit(num >> 28); \ + print_hexdigit(num >> 24); \ + print_hexdigit(num >> 20); \ + print_hexdigit(num >> 16); \ + print_hexdigit(num >> 12); \ + print_hexdigit(num >> 8); \ + print_hexdigit(num >> 4); \ + print_hexdigit(num >> 0); \ + }) + + /* Note: sub_program_main must not reference _any_ data or code outside of itself, + or leave interrupts enabled, due to the fact that it is probably erasing + & reloading the kernel. */ + + #define SET_SHORT(x,y) VSP((x)) = (y) + /*#define SET_SHORT(x,y) ({})*/ /*print_char('>');print_num(x);*/ /*printk("%8.8lx <= %04x\n", (x), (y))*/ + + #define SET_CHAR(x,y) VSC((x)) = (y) + /*#define SET_CHAR(x,y) ({})*/ /*print_char('>');print_num(x);*/ /*printk("%8.8lx <= %02x\n", (x), (y))*/ + + #define GET_SHORT(x) VSP((x)) + /*#define GET_SHORT(x) ({0;})*/ /*({print_char('<');print_num(x);0;})*/ /*(printk("%8.8lx => ....\n", (x)),0)*/ + + #define GET_CHAR(x) VSC((x)) + /*#define GET_CHAR(x) ({0;})*/ /*({print_char('<');print_num(x);0;})*/ /*(printk("%8.8lx => ..\n", (x)),0)*/ + + + void sub_program_main(struct arena_t * a, struct blkmem_program_t * prog) + { + volatile int i,l; + unsigned long base, offset, ptr, min, max; + unsigned char * c; + unsigned int erased = 0; + int failures; + int retry; + + cli(); + + retry = 0; + + again: + + SET_ALARM_LED(1); + + retry++; + + if (retry>5) { + goto give_up; + } + + print_char('\r'); + print_char('\n'); + print_char('R'); + print_char('0' + retry); + + failures = 0; + erased = 0; + + /* for(i=prog->blocks-1;i>=0;i--) {*/ + for(i=0;iblocks;i++) { + + SET_COMM_STATUS_LED(!GET_COMM_STATUS_LED()); + + print_char('\r'); + print_char('\n'); + print_num(prog->block[i].pos+a->address); + print_char('-'); + print_num(prog->block[i].pos+prog->block[i].length-1+a->address); + print_char('\r'); + print_char('\n'); + + if(prog->block[i].length > 0xE0000) + break; + + for(l=prog->block[i].pos / a->blksize; l <= ((prog->block[i].pos+prog->block[i].length-1) / a->blksize); l++) { + if (!test_bit(l, &erased)) { + + print_char('E'); + print_char('0' + l / 10); + print_char('0' + l % 10); + print_char('\r'); + print_char('\n'); + + if (l < 1) + break; + /*if (l >= 8) + break;*/ + + ptr = l * a->blksize; + offset = ptr % a->unitsize; + base = ptr - offset; + + base += a->address; + ptr += a->address; + + print_char('b'); + print_char('a'); + print_char('s'); + print_char('e'); + print_char(' '); + print_num(base); + print_char('\r'); + print_char('\n'); + print_char('o'); + print_char('f'); + print_char('f'); + print_char(' '); + print_num(offset); + print_char('\r'); + print_char('\n'); + print_char('p'); + print_char('t'); + print_char('r'); + print_char(' '); + print_num(ptr); + print_char('\r'); + print_char('\n'); + + set_bit(l, &erased); + + if (ptr < 0x020000) + break; + /*if (ptr >= 0x100000) + break;*/ + + print_num(ptr); + + SET_COMM_ERROR_LED(1); + + /* Erase even half of sector */ + SET_SHORT( (base | (0x5555 << 1)), 0xaa00); + SET_SHORT( (base | (0x2aaa << 1)), 0x5500); + SET_SHORT( (base | (0x5555 << 1)), 0x8000); + SET_SHORT( (base | (0x5555 << 1)), 0xaa00); + SET_SHORT( (base | (0x2aaa << 1)), 0x5500); + + SET_SHORT( ptr, 0x3000); + #ifdef original_erase_logic + while (!(GET_SHORT(ptr) & 0x8000)) + ; + #else + for (;;) { + unsigned int status = GET_SHORT(ptr); + if (status & 0x8000) { + /* Erase complete */ + break; + } + if (status & 0x2000) { + /* Check again */ + status = GET_SHORT(ptr); + if (status & 0x8000) { + /* Erase complete */ + break; + } + + /* Erase failed */ + print_char('F'); + + /* Reset FLASH unit */ + SET_SHORT( base, 0xf000); + + failures++; + + /* Continue (with unerased sector) */ + break; + } + } + #endif + + print_char(':'); + + /* Erase odd half of sector */ + SET_SHORT( (base | (0x5555 << 1)), 0x00aa); + SET_SHORT( (base | (0x2aaa << 1)), 0x0055); + SET_SHORT( (base | (0x5555 << 1)), 0x0080); + SET_SHORT( (base | (0x5555 << 1)), 0x00aa); + SET_SHORT( (base | (0x2aaa << 1)), 0x0055); + + SET_SHORT( ptr, 0x0030); + #ifdef original_erase_logic + while (!(GET_SHORT(ptr) & 0x0080)) + ; + #else + for (;;) { + unsigned int status = GET_SHORT(ptr); + if (status & 0x0080) { + /* Erase complete */ + break; + } + if (status & 0x0020) { + + /* Check again */ + status = GET_SHORT(ptr); + if (status & 0x0080) { + /* Erase complete */ + break; + } + + /* Erase failed */ + print_char('F'); + + /* Reset FLASH unit */ + SET_SHORT( base, 0x00f0); + + failures++; + + /* Continue (with unerased sector) */ + break; + } + } + #endif + + print_char(':'); + + #if 0 + probe = (volatile unsigned short*)(fbase + a->blksize * l); + *probe = 0x3000; + while (!(*probe & 0x8000)) + ; + + print_char('.'); + + /* Erase odd half of sector */ + *(unsigned volatile short *)(fbase | (0x5555 << 1))=0x00aa; + *(unsigned volatile short *)(fbase | (0x2aaa << 1))=0x0055; + *(unsigned volatile short *)(fbase | (0x5555 << 1))=0x0080; + *(unsigned volatile short *)(fbase | (0x5555 << 1))=0x00aa; + *(unsigned volatile short *)(fbase | (0x2aaa << 1))=0x0055; + + probe = (volatile unsigned short*)(fbase + a->blksize * l); + *probe = 0x0030; + while (!(*probe & 0x0080)) + break; + + print_char('.'); + #endif + + SET_COMM_ERROR_LED(0); + } + } + + + min = prog->block[i].pos+a->address; + max = prog->block[i].pos+prog->block[i].length+a->address; + for(ptr=min, c=prog->block[i].data; ptraddress) % a->unitsize; + base = ptr - offset; + + if (ptr < 0x020000) + break; + /*if (ptr >= 0x100000) + break;*/ + + /*print_char('.');*/ + + #if 0 + if ((fbase & 1) == 0) { /* Even bank */ + *(unsigned volatile short *)(fbase | (0x5555 << 1))=0xaa00; + *(unsigned volatile short *)(fbase | (0x2aaa << 1))=0x5500; + *(unsigned volatile short *)(fbase | (0x5555 << 1))=0xa000; + *(unsigned volatile short *)(fbase + (b & ~1)) =*c << 8; + } else { /* Odd bank */ + *(unsigned volatile short *)(fbase | (0x5555 << 1))=0x00aa; + *(unsigned volatile short *)(fbase | (0x2aaa << 1))=0x0055; + *(unsigned volatile short *)(fbase | (0x5555 << 1))=0x00a0; + *(unsigned volatile short *)(fbase + (b & ~1)) =*c; + } + + probe = (volatile unsigned char*)(fbase + b); + while (*probe != *c) + break; + #endif + + if ((ptr & 1) == 0) { /* Even bank */ + SET_SHORT( (base | (0x5555 << 1)), 0xaa00); + SET_SHORT( (base | (0x2aaa << 1)), 0x5500); + SET_SHORT( (base | (0x5555 << 1)), 0xa000); + SET_SHORT( (ptr & ~1), *c << 8); + } else { /* Odd bank */ + SET_SHORT( (base | (0x5555 << 1)), 0x00aa); + SET_SHORT( (base | (0x2aaa << 1)), 0x0055); + SET_SHORT( (base | (0x5555 << 1)), 0x00a0); + SET_SHORT( (ptr & ~1), *c); + } + + #ifdef original_write_logic + while (GET_CHAR(ptr) != *c) + ; + #else + for (;;) { + unsigned char status = GET_CHAR(ptr); + if ((status & 0x80) == (*c & 0x80)) { + /* Program complete */ + break; + } + if (status & 0x20) { + /* Check again */ + status = GET_CHAR(ptr); + if ((status & 0x80) == (*c & 0x80)) { + /* Program complete */ + break; + } + + /* Program failed */ + print_char('F'); + + /* Reset FLASH unit */ + if ((ptr & 1) == 0) { /* Even bank */ + SET_SHORT( base, 0xf000); + } else { /* Odd bank */ + SET_SHORT( base, 0x00f0); + } + + failures++; + + /* Continue */ + break; + } + } + #endif + + /*print_char(' ');*/ + } + } + + if (failures > 0) { + /* There were failures erasing the FLASH, so go back to the beginning and + try it all again -- for lack of anything better to do. */ + + print_char('!'); + goto again; + } + + give_up: + + SET_ALARM_LED(1); + + + HARD_RESET_NOW(); + + i = 1; + while(i) + ; + + } + + void program_main(struct arena_t * a, struct blkmem_program_t * prog) + { + int len; + void (*code)(struct arena_t*, struct blkmem_program_t *); + + printk("program_main entered, blocks = %d\n", prog->blocks); + + len = &program_main-&sub_program_main; + code = kmalloc(len, GFP_KERNEL); + memcpy(code, &sub_program_main, len); + + code(a, prog); + + kfree(code); + + /*sub_program_main(a, prog);*/ + } + #endif /* CONFIG_SHGLCORE */ + + int general_program_func(struct inode * inode, struct file * file, struct arena_t * a, struct blkmem_program_t * prog) + { + int i,block; + int err; + unsigned int erased = 0; + unsigned long pos = file->f_pos; + + /* Mandatory flush of all dirty buffers */ + fsync_dev(inode->i_rdev); + invalidate_buffers(inode->i_rdev); + + for(i=0;iblocks;i++) { + int min= prog->block[i].pos / a->blksize; + int max = (prog->block[i].pos + prog->block[i].length - 1) / a->blksize; + for(block=min; block <= max; block++) { + if (!test_bit(block, &erased)) { + printk("Erase of sector at pos %lx of arena %d (address %p)\n", block * a->blksize, MINOR(inode->i_rdev), (void*)(a->address+block*a->blksize)); + + /* Invoke erase function */ + a->erase_func(a, block * a->blksize); + set_bit(block, &erased); + } + } + + printk("Write of %lu bytes at pos %lu (data at %p)\n", prog->block[i].length, prog->block[i].pos, prog->block[i].data); + + a->write_func(a, prog->block[i].pos, prog->block[i].length, prog->block[i].data); + + schedule(); + } + + if (prog->reset) + HARD_RESET_NOW(); + return 0; + } + + + static void complete_request(void * data); + + static struct tq_struct complete_tq = {0, 0, complete_request, NULL}; + + static void + delay_request( void ) + { + queue_task(&complete_tq, &tq_scheduler); + } + + static void + complete_request( void * data) + { + unsigned long start; + unsigned long len; + struct arena_t * a = arena + DEVICE_NR(CURRENT_DEV); + + for(;;) { + + /* sectors are 512 bytes */ + start = CURRENT->sector << 9; + len = CURRENT->current_nr_sectors << 9; + + /*printk("blkmem: re-request %d\n", CURRENT->cmd);*/ + + if ( CURRENT->cmd == READ ) { + /*printk("BMre-Read: %lx:%lx > %p\n", a->address + start, len, CURRENT->buffer);*/ + a->read_func(a, start, len, CURRENT->buffer); + } + else if (CURRENT->cmd == WRITE) { + /*printk("BMre-Write: %p > %lx:%lx\n", CURRENT->buffer, a->address + start, len);*/ + a->write_func(a, start, len, CURRENT->buffer); + } + /*printk("ending blkmem request\n");*/ + end_request( TRUE ); + + INIT_REQUEST; + } + + #if 0 + if (CURRENT) + do_blkmem_request(); /* Process subsequent requests */ + #endif + } + + + static void + do_blkmem_request( void ) + { + unsigned long start; + unsigned long len; + struct arena_t * a = arena + DEVICE_NR(CURRENT_DEV); + #if 0 + printk( KERN_ERR DEVICE_NAME ": request\n"); + #endif + while ( TRUE ) { + INIT_REQUEST; + + /* sectors are 512 bytes */ + start = CURRENT->sector << 9; + len = CURRENT->current_nr_sectors << 9; + + if ((start + len) > a->length) { + printk( KERN_ERR DEVICE_NAME ": bad access: block=%ld, count=%ld (pos=%lx, len=%lx)\n", + CURRENT->sector, + CURRENT->current_nr_sectors, + start+len, + a->length); + end_request( FALSE ); + continue; + } + + /*printk("blkmem: request %d\n", CURRENT->cmd);*/ + + if ( ( CURRENT->cmd != READ ) + && ( CURRENT->cmd != WRITE ) + ) { + printk( KERN_ERR DEVICE_NAME ": bad command: %d\n", CURRENT->cmd ); + end_request( FALSE ); + continue; + } + + if ( CURRENT->cmd == READ ) { + /*printk("BMRead %d, pid %d: %lx:%lx > %p\n", DEVICE_NR(CURRENT_DEV), current->pid, a->address + start, len, CURRENT->buffer);*/ + if (a->read_func) { + delay_request(); + return; + /*a->read_func(a, start, len, CURRENT->buffer);*/ + } + else + memcpy( CURRENT->buffer, (void*)(a->address + start), len ); + } + else if (CURRENT->cmd == WRITE) { + /*printk("BMWrite %d: %p > %lx:%lx\n", DEVICE_NR(CURRENT_DEV), CURRENT->buffer, a->address + start, len);*/ + if (a->write_func) { + delay_request(); + return; + /*a->write_func(a, start, len, CURRENT->buffer);*/ + } else + memcpy( (void*)(a->address + start), CURRENT->buffer, len ); + } + /*printk("ending blkmem request\n");*/ + end_request( TRUE ); + } + } + + + #ifdef MAGIC_ROM_PTR + static int + blkmem_romptr( struct inode *inode, struct file *filp, struct vm_area_struct * vma) + { + struct arena_t * a = arena + MINOR(inode->i_rdev); + + if (a->read_func) + return -ENOSYS; /* Can't do it, as this arena isn't in the main address space */ + + vma->vm_start = a->address + vma->vm_offset; + return 0; + } + #endif + + static int blkmem_ioctl (struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) + { + struct arena_t * a = arena + MINOR(inode->i_rdev); + int err; + + switch (cmd) { + case BMGETSIZES: /* Return device size in sectors */ + + if (!arg) + return -EINVAL; + + err = verify_area(VERIFY_WRITE, (unsigned long *) arg, sizeof(unsigned long)); + if (err) + return err; + + put_user(a->blksize ? (a->length / a->blksize) : 0, (unsigned long *) arg); + + break; + + case BMGETSIZEB: /* Return device size in bytes */ + + if (!arg) + return -EINVAL; + + err = verify_area(VERIFY_WRITE, (unsigned long *) arg, sizeof(unsigned long)); + if (err) + return err; + + put_user(a->length, (unsigned long *) arg); + + break; + + case BMSERASE: + if (a->erase_func) { + + printk("Erase of sector at pos %lx of arena %d (address %p)\n", arg, MINOR(inode->i_rdev), (void*)(a->address+arg)); + + if (arg >= a->length) + return -EINVAL; + + /* Mandatory flush of all dirty buffers */ + fsync_dev(inode->i_rdev); + + /* Invalidate any buffers pointing to the section that will be erased */ + invalidate_buffers_by_byte(inode->i_rdev, arg * a->blksize, a->blksize); + + /* Invoke erase function */ + a->erase_func(a, arg); + } else + return -EINVAL; + break; + + case BMSGSIZE: + + if (!arg) + return -EINVAL; + + err = verify_area(VERIFY_WRITE, (unsigned long*)arg, sizeof(unsigned long)); + if (err) + return err; + + put_user(a->blksize, (unsigned long*)arg); + break; + + case BMSGERASEVALUE: + err = verify_area(VERIFY_WRITE, (unsigned char*)arg, sizeof(unsigned char)); + if (err) + return err; + + *(unsigned char*)arg = a->erasevalue; + break; + + case BMPROGRAM: + { + struct blkmem_program_t * prog; + int i; + if (!arg) + return -EINVAL; + + prog = (struct blkmem_program_t*)arg; + + /* Extensive checks to verify that the programming data makes sense */ + + err = verify_area(VERIFY_READ, prog, sizeof(struct blkmem_program_t)); + if (err) + return err; + + if ((prog->magic1 != BMPROGRAM_MAGIC_1) || + (prog->magic2 != BMPROGRAM_MAGIC_2)) + return -EINVAL; + + err = verify_area(VERIFY_READ, prog, sizeof(struct blkmem_program_t) + sizeof(prog->block[0]) * prog->blocks); + if (err) + return err; + + for(i=0;iblocks;i++) + if(prog->block[i].magic3 != BMPROGRAM_MAGIC_3) + return -EINVAL; + + for(i=0;iblocks;i++) + if ((prog->block[i].pos > a->length) || + ((prog->block[i].pos+prog->block[i].length-1) > a->length)) + return -EINVAL; + + for(i=0;iblocks;i++) { + err = verify_area(VERIFY_READ, prog->block[i].data, prog->block[i].length); + if (err) + return err; + } + + if (a->program_func) { + a->program_func(a, prog); + } else { + return general_program_func(inode, file, a, prog); + } + + break; + } + default: + return -EINVAL; + } + return 0; + } + + static int + blkmem_open( struct inode *inode, struct file *filp ) + { + int device; + struct arena_t * a; + + device = DEVICE_NR( inode->i_rdev ); + #if 0 + printk( KERN_ERR DEVICE_NAME ": open: %d\n", device ); + #endif + + if ((MINOR(device) < 0) || (MINOR(device) >= arenas)) { + printk("arena open of %d failed!\n", MINOR(device)); + return -ENODEV; + } + + a = &arena[MINOR(device)]; + + #ifdef DEBUG + printk("Open of blkmem arena %d at %lx, length %lx\n", MINOR(device), a->address, a->length); + #endif + + #if defined(MODULE) + MOD_INC_USE_COUNT; + #endif + return 0; + } + + static void + blkmem_release( struct inode *inode, struct file *filp ) + { + #if 0 + printk( KERN_ERR DEVICE_NAME ": release: %d\n", current_device ); + #endif + + fsync_dev( inode->i_rdev ); + + #if defined(MODULE) + MOD_DEC_USE_COUNT; + #endif + + return; + } + + static struct file_operations blkmem_fops = + { + NULL, /* lseek - default */ + block_read, /* read - general block-dev read */ + block_write, /* write - general block-dev write */ + NULL, /* readdir - bad */ + NULL, /* poll */ + blkmem_ioctl, /* ioctl */ + NULL, + blkmem_open, /* open */ + blkmem_release, /* release */ + block_fsync, /* fsync */ + NULL, /* fasync */ + NULL, /* check media change */ + NULL, /* revalidate */ + #ifdef MAGIC_ROM_PTR + blkmem_romptr /* romptr */ + #else + NULL + #endif + }; + + int + blkmem_init( void ) + { + int i; + if ( register_blkdev( MAJOR_NR, DEVICE_NAME, &blkmem_fops )) { + printk( KERN_ERR DEVICE_NAME ": Unable to get major %d\n", + MAJOR_NR ); + return -EBUSY; + } + + #ifdef FIXUP_ARENAS + { + FIXUP_ARENAS + } + #endif + + for(i=0;i> 10; /* Round up */ + arena[i].length = blkmem_sizes[i] << 10; + } + printk("Blkmem copyright 1998,1999 D. Jeff Dionne\nBlkmem copyright 1998 Kenneth Albanowski\nBlkmem %ld disk images:\n", arenas); + + for(i=0;i #include ! #include "blk.h" /* * The request-struct contains all necessary data --- 19,25 ---- #include #include ! #include /* * The request-struct contains all necessary data *************** *** 36,46 **** /* * used to wait on when there are no free requests */ ! struct wait_queue * wait_for_request; /* This specifies how many sectors to read ahead on the disk. */ ! int read_ahead[MAX_BLKDEV]; /* blk_dev_struct is: * *request_fn --- 36,46 ---- /* * used to wait on when there are no free requests */ ! struct wait_queue * wait_for_request = NULL; /* This specifies how many sectors to read ahead on the disk. */ ! int read_ahead[MAX_BLKDEV] = {0, }; /* blk_dev_struct is: * *request_fn *************** *** 56,62 **** * * if (!blk_size[MAJOR]) then no minor size checking is done. */ ! int * blk_size[MAX_BLKDEV]; /* * blksize_size contains the size of all block-devices: --- 56,62 ---- * * if (!blk_size[MAJOR]) then no minor size checking is done. */ ! int * blk_size[MAX_BLKDEV] = { NULL, NULL, }; /* * blksize_size contains the size of all block-devices: *************** *** 65,71 **** * * if (!blksize_size[MAJOR]) then 1024 bytes is assumed. */ ! int * blksize_size[MAX_BLKDEV]; /* * hardsect_size contains the size of the hardware sector of a device. --- 65,71 ---- * * if (!blksize_size[MAJOR]) then 1024 bytes is assumed. */ ! int * blksize_size[MAX_BLKDEV] = { NULL, NULL, }; /* * hardsect_size contains the size of the hardware sector of a device. *************** *** 79,87 **** * This is currently set by some scsi device and read by the msdos fs driver * This might be a some uses later. */ ! int * hardsect_size[MAX_BLKDEV]; /* * remove the plug and let it rip.. */ void unplug_device(void * data) --- 79,111 ---- * This is currently set by some scsi device and read by the msdos fs driver * This might be a some uses later. */ ! int * hardsect_size[MAX_BLKDEV] = { NULL, NULL, }; /* + * Max number of sectors per request + */ + int * max_sectors[MAX_BLKDEV] = { NULL, NULL, }; + + /* + * Max number of segments per request + */ + int * max_segments[MAX_BLKDEV] = { NULL, NULL, }; + + static inline int get_max_sectors(kdev_t dev) + { + if (!max_sectors[MAJOR(dev)]) + return MAX_SECTORS; + return max_sectors[MAJOR(dev)][MINOR(dev)]; + } + + static inline int get_max_segments(kdev_t dev) + { + if (!max_segments[MAJOR(dev)]) + return MAX_SEGMENTS; + return max_segments[MAJOR(dev)][MINOR(dev)]; + } + + /* * remove the plug and let it rip.. */ void unplug_device(void * data) *************** *** 89,95 **** struct blk_dev_struct * dev = (struct blk_dev_struct *) data; unsigned long flags; ! save_flags_cli(flags); if (dev->current_request == &dev->plug) { struct request * next = dev->plug.next; dev->current_request = next; --- 113,120 ---- struct blk_dev_struct * dev = (struct blk_dev_struct *) data; unsigned long flags; ! save_flags(flags); ! cli(); if (dev->current_request == &dev->plug) { struct request * next = dev->plug.next; dev->current_request = next; *************** *** 232,253 **** void add_request(struct blk_dev_struct * dev, struct request * req) { struct request * tmp; short disk_index; ! switch (MAJOR(req->rq_dev)) { case SCSI_DISK_MAJOR: ! disk_index = (MINOR(req->rq_dev) & 0x0070) >> 4; if (disk_index < 4) drive_stat_acct(req->cmd, req->nr_sectors, disk_index); break; case IDE0_MAJOR: /* same as HD_MAJOR */ case XT_DISK_MAJOR: ! disk_index = (MINOR(req->rq_dev) & 0x0040) >> 6; drive_stat_acct(req->cmd, req->nr_sectors, disk_index); break; case IDE1_MAJOR: ! disk_index = ((MINOR(req->rq_dev) & 0x0040) >> 6) + 2; drive_stat_acct(req->cmd, req->nr_sectors, disk_index); default: break; --- 257,285 ---- void add_request(struct blk_dev_struct * dev, struct request * req) { + int major = MAJOR(req->rq_dev); + int minor = MINOR(req->rq_dev); struct request * tmp; short disk_index; ! switch (major) { ! case DAC960_MAJOR+0: ! disk_index = (minor & 0x00f8) >> 3; ! if (disk_index < 4) ! drive_stat_acct(req->cmd, req->nr_sectors, disk_index); ! break; case SCSI_DISK_MAJOR: ! disk_index = (minor & 0x0070) >> 4; if (disk_index < 4) drive_stat_acct(req->cmd, req->nr_sectors, disk_index); break; case IDE0_MAJOR: /* same as HD_MAJOR */ case XT_DISK_MAJOR: ! disk_index = (minor & 0x0040) >> 6; drive_stat_acct(req->cmd, req->nr_sectors, disk_index); break; case IDE1_MAJOR: ! disk_index = ((minor & 0x0040) >> 6) + 2; drive_stat_acct(req->cmd, req->nr_sectors, disk_index); default: break; *************** *** 273,302 **** tmp->next = req; /* for SCSI devices, call request_fn unconditionally */ ! if (scsi_blk_major(MAJOR(req->rq_dev))) (dev->request_fn)(); sti(); } - - #define MAX_SECTORS 244 ! static inline void attempt_merge (struct request *req) { struct request *next = req->next; if (!next) return; if (req->sector + req->nr_sectors != next->sector) return; ! if (next->sem || req->cmd != next->cmd || req->rq_dev != next->rq_dev || req->nr_sectors + next->nr_sectors >= MAX_SECTORS) return; ! #if 0 ! printk ("%s: merge %ld, %ld + %ld == %ld\n", kdevname(req->rq_dev), req->sector, req->nr_sectors, next->nr_sectors, req->nr_sectors + next->nr_sectors); ! #endif req->bhtail->b_reqnext = next->bh; req->bhtail = next->bhtail; req->nr_sectors += next->nr_sectors; next->rq_status = RQ_INACTIVE; req->next = next->next; wake_up (&wait_for_request); --- 305,343 ---- tmp->next = req; /* for SCSI devices, call request_fn unconditionally */ ! if (scsi_blk_major(major)) (dev->request_fn)(); + if ( (major >= DAC960_MAJOR+0 && major <= DAC960_MAJOR+7) || + (major >= COMPAQ_SMART2_MAJOR+0 && major <= COMPAQ_SMART2_MAJOR+7)) + (dev->request_fn)(); + sti(); } ! static inline void attempt_merge (struct request *req, ! int max_sectors, ! int max_segments) { struct request *next = req->next; + int total_segments; if (!next) return; if (req->sector + req->nr_sectors != next->sector) return; ! if (next->sem || req->cmd != next->cmd || req->rq_dev != next->rq_dev || ! req->nr_sectors + next->nr_sectors > max_sectors) return; ! total_segments = req->nr_segments + next->nr_segments; ! if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) ! total_segments--; ! if (total_segments > max_segments) ! return; req->bhtail->b_reqnext = next->bh; req->bhtail = next->bhtail; req->nr_sectors += next->nr_sectors; + req->nr_segments = total_segments; next->rq_status = RQ_INACTIVE; req->next = next->next; wake_up (&wait_for_request); *************** *** 306,312 **** { unsigned int sector, count; struct request * req; ! int rw_ahead, max_req; count = bh->b_size >> 9; sector = bh->b_rsector; --- 347,353 ---- { unsigned int sector, count; struct request * req; ! int rw_ahead, max_req, max_sectors, max_segments; count = bh->b_size >> 9; sector = bh->b_rsector; *************** *** 323,329 **** lock_buffer(bh); if (blk_size[major]) ! if (blk_size[major][MINOR(bh->b_rdev)] < (sector + count)>>1) { bh->b_state &= (1 << BH_Lock) | (1 << BH_FreeOnIO); /* This may well happen - the kernel calls bread() without checking the size of the device, e.g., --- 364,370 ---- lock_buffer(bh); if (blk_size[major]) ! if (blk_size[major][MINOR(bh->b_rdev)] < (sector + count)>>1) { bh->b_state &= (1 << BH_Lock) | (1 << BH_FreeOnIO); /* This may well happen - the kernel calls bread() without checking the size of the device, e.g., *************** *** 389,394 **** --- 430,438 ---- /* * Try to coalesce the new request with old requests */ + max_sectors = get_max_sectors(bh->b_rdev); + max_segments = get_max_segments(bh->b_rdev); + cli(); req = blk_dev[major].current_request; if (!req) { *************** *** 401,407 **** case FLOPPY_MAJOR: case IDE2_MAJOR: case IDE3_MAJOR: - case XT_DISK_MAJOR: /* * The scsi disk and cdrom drivers completely remove the request * from the queue when they start processing an entry. For this --- 445,450 ---- *************** *** 418,442 **** case SCSI_DISK_MAJOR: case SCSI_CDROM_MAJOR: ! do { if (req->sem) continue; if (req->cmd != rw) continue; ! if (req->nr_sectors >= MAX_SECTORS) continue; if (req->rq_dev != bh->b_rdev) continue; /* Can we add it to the end of this request? */ if (req->sector + req->nr_sectors == sector) { req->bhtail->b_reqnext = bh; req->bhtail = bh; ! req->nr_sectors += count; /* Can we now merge this req with the next? */ ! attempt_merge(req); /* or to the beginning? */ } else if (req->sector - count == sector) { bh->b_reqnext = req->bh; req->bh = bh; req->buffer = bh->b_data; --- 461,512 ---- case SCSI_DISK_MAJOR: case SCSI_CDROM_MAJOR: ! case DAC960_MAJOR+0: ! case DAC960_MAJOR+1: ! case DAC960_MAJOR+2: ! case DAC960_MAJOR+3: ! case DAC960_MAJOR+4: ! case DAC960_MAJOR+5: ! case DAC960_MAJOR+6: ! case DAC960_MAJOR+7: ! case COMPAQ_SMART2_MAJOR+0: ! case COMPAQ_SMART2_MAJOR+1: ! case COMPAQ_SMART2_MAJOR+2: ! case COMPAQ_SMART2_MAJOR+3: ! case COMPAQ_SMART2_MAJOR+4: ! case COMPAQ_SMART2_MAJOR+5: ! case COMPAQ_SMART2_MAJOR+6: ! case COMPAQ_SMART2_MAJOR+7: do { if (req->sem) continue; if (req->cmd != rw) continue; ! if (req->nr_sectors + count > max_sectors) continue; if (req->rq_dev != bh->b_rdev) continue; /* Can we add it to the end of this request? */ if (req->sector + req->nr_sectors == sector) { + if (req->bhtail->b_data + req->bhtail->b_size + != bh->b_data) { + if (req->nr_segments < max_segments) + req->nr_segments++; + else continue; + } req->bhtail->b_reqnext = bh; req->bhtail = bh; ! req->nr_sectors += count; /* Can we now merge this req with the next? */ ! attempt_merge(req, max_sectors, max_segments); /* or to the beginning? */ } else if (req->sector - count == sector) { + if (bh->b_data + bh->b_size + != req->bh->b_data) { + if (req->nr_segments < max_segments) + req->nr_segments++; + else continue; + } bh->b_reqnext = req->bh; req->bh = bh; req->buffer = bh->b_data; *************** *** 470,475 **** --- 540,546 ---- req->errors = 0; req->sector = sector; req->nr_sectors = count; + req->nr_segments = 1; req->current_nr_sectors = count; req->buffer = bh->b_data; req->sem = NULL; *************** *** 634,639 **** --- 705,711 ---- req[j]->errors = 0; req[j]->sector = rsector; req[j]->nr_sectors = buffersize >> 9; + req[j]->nr_segments = 1; req[j]->current_nr_sectors = buffersize >> 9; req[j]->buffer = buf; req[j]->sem = &sem; *************** *** 673,681 **** --- 745,759 ---- #ifdef CONFIG_BLK_DEV_RAM rd_init(); #endif + #ifdef CONFIG_BLK_DEV_BLKMEM + blkmem_init(); + #endif #ifdef CONFIG_BLK_DEV_LOOP loop_init(); #endif + #ifdef CONFIG_CDI_INIT + cdi_init(); /* this MUST precede ide_init */ + #endif CONFIG_CDI_INIT #ifdef CONFIG_BLK_DEV_IDE ide_init(); /* this MUST precede hd_init */ #endif *************** *** 685,697 **** #ifdef CONFIG_BLK_DEV_XD xd_init(); #endif #ifdef CONFIG_BLK_DEV_FD floppy_init(); #else - #if !defined(CONFIG_ARCH_ARC) && !defined(CONFIG_ARCH_SA110EVAL) outb_p(0xc, 0x3f2); - #endif #endif #ifdef CONFIG_BLK_DEV_MD md_init(); #endif CONFIG_BLK_DEV_MD --- 763,806 ---- #ifdef CONFIG_BLK_DEV_XD xd_init(); #endif + #ifdef CONFIG_PARIDE + { extern void paride_init(void); paride_init(); }; + #endif #ifdef CONFIG_BLK_DEV_FD floppy_init(); #else outb_p(0xc, 0x3f2); #endif + #ifdef CONFIG_CDU31A + cdu31a_init(); + #endif CONFIG_CDU31A + #ifdef CONFIG_MCD + mcd_init(); + #endif CONFIG_MCD + #ifdef CONFIG_MCDX + mcdx_init(); + #endif CONFIG_MCDX + #ifdef CONFIG_SBPCD + sbpcd_init(); + #endif CONFIG_SBPCD + #ifdef CONFIG_AZTCD + aztcd_init(); + #endif CONFIG_AZTCD + #ifdef CONFIG_CDU535 + sony535_init(); + #endif CONFIG_CDU535 + #ifdef CONFIG_GSCD + gscd_init(); + #endif CONFIG_GSCD + #ifdef CONFIG_CM206 + cm206_init(); + #endif + #ifdef CONFIG_OPTCD + optcd_init(); + #endif CONFIG_OPTCD + #ifdef CONFIG_SJCD + sjcd_init(); + #endif CONFIG_SJCD #ifdef CONFIG_BLK_DEV_MD md_init(); #endif CONFIG_BLK_DEV_MD Index: AplioTRIO/linux/arch/armnommu/drivers/block/rd.c diff -c AplioTRIO/linux/arch/armnommu/drivers/block/rd.c:1.1.1.1 AplioTRIO/linux/arch/armnommu/drivers/block/rd.c:1.2 *** AplioTRIO/linux/arch/armnommu/drivers/block/rd.c:1.1.1.1 Mon Nov 15 14:42:35 1999 --- AplioTRIO/linux/arch/armnommu/drivers/block/rd.c Mon Dec 27 20:21:06 1999 *************** *** 35,46 **** --- 35,51 ---- * * 4/25/96 : Made ramdisk size a parameter (default is now 4MB) * - Chad Page + * + * Support added for releasing empty (all zero) blocks + * -- Kenneth Albanowski + * */ #include #include #include #include + #include #include #include #include *************** *** 53,58 **** --- 58,64 ---- #include #include + #include extern void wait_for_keypress(void); *************** *** 139,149 **** * If we're writing, we protect the buffer. */ ! if (CURRENT->cmd == READ) memset(CURRENT->buffer, 0, len); ! else set_bit(BH_Protected, &CURRENT->bh->b_state); end_request(1); goto repeat; } --- 145,180 ---- * If we're writing, we protect the buffer. */ ! #ifndef CONFIG_RD_RELEASE_BLOCKS ! if (CURRENT->cmd == READ) { memset(CURRENT->buffer, 0, len); ! } ! else set_bit(BH_Protected, &CURRENT->bh->b_state); + #else /* CONFIG_RD_RELEASE_BLOCKS*/ + + /* But we'll unprotect it if it's empty. */ + if (CURRENT->cmd == READ) { + memset(CURRENT->buffer, 0, len); + } + else + { + int i=0; + + for(i=0;ibuffer[i] != 0) + break; + + if (ibh->b_state); + } + else { + clear_bit(BH_Protected, &CURRENT->bh->b_state); + } + } + #endif /* CONFIG_RD_RELEASE_BLOCKS*/ + end_request(1); goto repeat; } *************** *** 327,332 **** --- 358,364 ---- * We currently check for the following magic numbers: * minix * ext2 + * romfs * gzip */ int *************** *** 335,340 **** --- 367,373 ---- const int size = 512; struct minix_super_block *minixsb; struct ext2_super_block *ext2sb; + struct romfs_super_block *romfsb; int nblocks = -1; int max_blocks; unsigned char *buf; *************** *** 345,350 **** --- 378,384 ---- minixsb = (struct minix_super_block *) buf; ext2sb = (struct ext2_super_block *) buf; + romfsb = (struct romfs_super_block *) buf; memset(buf, 0xe5, size); /* *************** *** 367,372 **** --- 401,416 ---- goto done; } + /* romfs is at block zero too */ + if (romfsb->word0 == ROMSB_WORD0 && + romfsb->word1 == ROMSB_WORD1) { + printk(KERN_NOTICE + "RAMDISK: Romfs filesystem found at block %d\n", + start_block); + nblocks = (ntohl(romfsb->size)+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; + goto done; + } + /* * Read block 1 to test for minix and ext2 superblock */ *************** *** 395,400 **** --- 439,445 ---- nblocks = ext2sb->s_blocks_count; goto done; } + printk(KERN_NOTICE "RAMDISK: Couldn't find valid ramdisk image starting at %d.\n", start_block); Index: AplioTRIO/linux/arch/armnommu/drivers/char/Config.in diff -c AplioTRIO/linux/arch/armnommu/drivers/char/Config.in:1.2 AplioTRIO/linux/arch/armnommu/drivers/char/Config.in:1.3 *** AplioTRIO/linux/arch/armnommu/drivers/char/Config.in:1.2 Tue Nov 16 16:10:13 1999 --- AplioTRIO/linux/arch/armnommu/drivers/char/Config.in Tue Jan 25 18:20:55 2000 *************** *** 18,23 **** --- 18,26 ---- fi bool 'Support for user misc device modules' CONFIG_UMISC + if [ "$CONFIG_UMISC" != "n" ]; then + tristate 'Support for TRIO ports device' CONFIG_TRIO_PORTS + fi bool 'Watchdog Timer Support' CONFIG_WATCHDOG if [ "$CONFIG_WATCHDOG" != "n" ]; then Index: AplioTRIO/linux/arch/armnommu/drivers/char/Makefile diff -c AplioTRIO/linux/arch/armnommu/drivers/char/Makefile:1.2 AplioTRIO/linux/arch/armnommu/drivers/char/Makefile:1.5 *** AplioTRIO/linux/arch/armnommu/drivers/char/Makefile:1.2 Mon Nov 15 17:26:14 1999 --- AplioTRIO/linux/arch/armnommu/drivers/char/Makefile Thu Jan 27 17:58:57 2000 *************** *** 77,85 **** L_OBJS += console-dummy.o vt-dummy.o endif ! ifeq ($(MACHINE),trio) ! L_OBJS += console-trio.o vt-dummy.o kbd_trio.o endif # Common dependencies --- 77,96 ---- L_OBJS += console-dummy.o vt-dummy.o endif ! ! ifeq ($(CONFIG_CONSOLE),y) ! ifeq ($(CONFIG_FRAMEBUFFER),y) ! LX_OBJS += fbmem.o ! endif ! ! ifeq ($(MACHINE),trio) ! L_OBJS += console-trio.o vt-dummy.o kbd_trio.o ! else ! L_OBJS += console.o vc_screen.o consolemap.o selection.o vt.o ! endif endif + + # Common dependencies *************** *** 147,155 **** --- 158,172 ---- ifdef M L_OBJS += misc.o + ifeq ($(CONFIG_TRIO_PORTS), y) + L_OBJS += trioport.o triokb.o + endif else ifdef MM M_OBJS += misc.o + ifeq ($(CONFIG_TRIO_PORTS), m) + M_OBJS += trioport.o triokb.o + endif endif endif Index: AplioTRIO/linux/arch/armnommu/drivers/char/mem.c diff -c AplioTRIO/linux/arch/armnommu/drivers/char/mem.c:1.1.1.1 AplioTRIO/linux/arch/armnommu/drivers/char/mem.c:1.3 *** AplioTRIO/linux/arch/armnommu/drivers/char/mem.c:1.1.1.1 Mon Nov 15 14:42:34 1999 --- AplioTRIO/linux/arch/armnommu/drivers/char/mem.c Tue Jan 25 18:20:00 2000 *************** *** 100,105 **** --- 100,106 ---- return 0; } + #ifdef CONFIG_CONSOLE static int read_fb(struct inode * inode, struct file *file, char *buf, int count) { if (count < 0) *************** *** 141,146 **** --- 142,149 ---- return 0; } + #endif + static int read_kmem(struct inode *inode, struct file *file, char *buf, int count) { int read1, read2; *************** *** 297,302 **** --- 300,306 ---- NULL /* fsync */ }; + #ifdef CONFIG_CONSOLE static struct file_operations fb_fops = { memory_lseek, read_fb, *************** *** 309,314 **** --- 313,319 ---- NULL, /* no special release code */ NULL /* fsync */ }; + #endif static struct file_operations kmem_fops = { memory_lseek, *************** *** 403,411 **** --- 408,418 ---- case 9: filp->f_op = &urandom_fops; break; + #ifdef CONFIG_CONSOLE case 128: filp->f_op = &fb_fops; break; + #endif default: return -ENXIO; } *************** *** 436,442 **** #ifdef CONFIG_PRINTER lp_init(); #endif ! #if defined(CONFIG_MOUSE) || defined(CONFIG_SOFT_WATCHDOG) misc_init(); #endif #ifdef CONFIG_SOUND --- 443,449 ---- #ifdef CONFIG_PRINTER lp_init(); #endif ! #if defined(CONFIG_MOUSE) || defined(CONFIG_SOFT_WATCHDOG) || defined(CONFIG_TRIO_PORTS) misc_init(); #endif #ifdef CONFIG_SOUND Index: AplioTRIO/linux/arch/armnommu/drivers/char/misc.c diff -c AplioTRIO/linux/arch/armnommu/drivers/char/misc.c:1.1.1.1 AplioTRIO/linux/arch/armnommu/drivers/char/misc.c:1.3 *** AplioTRIO/linux/arch/armnommu/drivers/char/misc.c:1.1.1.1 Mon Nov 15 14:42:34 1999 --- AplioTRIO/linux/arch/armnommu/drivers/char/misc.c Thu Jan 27 17:57:42 2000 *************** *** 61,66 **** --- 61,67 ---- static unsigned char misc_minors[DYNAMIC_MINORS / 8]; #ifndef MODULE + int trioport_init(void); extern void watchdog_init(void); extern int arch_mouse_init(void); extern int con_get_info(int *mode, int *shift, int *col, int *row, *************** *** 173,179 **** #include X(misc_register), X(misc_deregister), ! #ifndef MODULE X(set_selection), /* used by the kmouse module, can only */ X(paste_selection), /* be exported if misc.c is in linked in */ X(con_get_info), --- 174,180 ---- #include X(misc_register), X(misc_deregister), ! #if !defined(MODULE) && defined(CONFIG_CONSOLE) X(set_selection), /* used by the kmouse module, can only */ X(paste_selection), /* be exported if misc.c is in linked in */ X(con_get_info), *************** *** 183,188 **** --- 184,193 ---- int misc_init(void) { + #ifdef CONFIG_TRIO_PORTS + trioport_init(); + triokb_init(); + #endif #ifndef MODULE #ifdef CONFIG_PROC_FS proc_register_dynamic(&proc_root, &(struct proc_dir_entry) { Index: AplioTRIO/linux/arch/armnommu/drivers/char/triokb.c diff -c /dev/null AplioTRIO/linux/arch/armnommu/drivers/char/triokb.c:1.1 *** /dev/null Fri Jan 28 16:54:03 2000 --- AplioTRIO/linux/arch/armnommu/drivers/char/triokb.c Thu Jan 27 17:58:44 2000 *************** *** 0 **** --- 1,241 ---- + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include "triopio.h" + /* + * We sponge a minor off of the misc major. No need slurping + * up another valuable major dev number for this. + */ + + #define TRIOKB_MINOR 178 + + static struct wait_queue *user_queue = NULL; + static struct tq_struct kb_poll; + + + struct pio_handler kb_handler; + static struct triokb_piomask kb_mask; + static unsigned char keyinfo, last_keys; + static int pa_raws[31]; + static int pb_raws[31]; + static int cols[63]; + static int pa_rawnb; + static int pb_rawnb; + static int colnb; + static int key_cnt; + + u_32 col, cola, colb; + + + static int calc_tables(void){ + int i,j; + j=0; + pa_rawnb=pb_rawnb=colnb=0; + memset(pa_raws, 0, sizeof(pa_raws)); + memset(pb_raws, 0, sizeof(pb_raws)); + for(i=0;i<32;i++){ + if(kb_mask.pra_mask >> i & 1){ + pa_raws[j++] = 1<> i & 1){ + pb_raws[j++] = 1<> i & 1){ + cols[i] = j++; + printk("col%d = %x\n", i, cols[i]); + colnb++; + } + for(i=0;i<32;i++){ + if(kb_mask.pcb_mask >> i & 1){ + cols[i+32] = j++; + printk("col%d = %x\n", i+32, cols[i+32]); + colnb++; + } + } + } + printk("araws %d braws %d columns %d\n", pa_rawnb, pb_rawnb, colnb); + return(colnb); + } + static u_32 getkey(u_32 cola, u_32 colb){ + int j; + j=0; + col = 0; + while(j<32){ + if((col = cola >> j & 1)){ + col = cols[j]; + break; + } + j++; + } + if (!col){ + j=0; + while(j<32){ + if((col = colb >> j & 1)){ + col = cols[j+32]; + break; + } + j++; + } + } + return(col); + } + static unsigned char kb_input_key(void){ + int i; + trioport_set_out(kb_handler.pa, kb_mask.pra_mask,kb_mask.pra_mask ); + trioport_set_out(kb_handler.pa, kb_mask.prb_mask,kb_mask.prb_mask ); + + for(i=0; ibase->pdsr) & kb_mask.pca_mask; + colb = ~(kb_handler.pb->base->pdsr) & kb_mask.pcb_mask; + trioport_set_out(kb_handler.pa, pa_raws[i], 1); + if (cola || colb){ + col = getkey(cola, colb); + if(!col){ + printk("kb_input_key error\n"); + } + // printk("araw %d col %d ", i, col); + return(col + i * colnb); + } + } + for(i=0; i< pb_rawnb; i++){ + trioport_set_out(kb_handler.pb, pb_raws[i], 0); + cola = ~(kb_handler.pa->base->pdsr) & kb_mask.pca_mask; + colb = ~(kb_handler.pb->base->pdsr) & kb_mask.pcb_mask; + if (cola || colb){ + col = getkey(cola, colb); + if(!col){ + printk("kb_input_key error\n"); + } + // printk("braw %d col %d ", i, col); + return(col + (i+pa_rawnb) * colnb); + } + } + return 0; + } + static void kbpoll(void *data){ + unsigned char keys; + keyinfo = 0; + keys = kb_input_key(); + if (keys && (keys == last_keys)){ + if(++key_cnt > 4){ + keyinfo = keys; + printk("Key %d\n", keys); + key_cnt = 0; + } + }else{ + key_cnt=0; + } + last_keys = keys; + if (keyinfo && user_queue){ + wake_up_interruptible(&user_queue); + } + queue_task_irq_off(&kb_poll, &tq_timer); + } + static int triokb_read(struct inode *inode, struct file *file, char *buffer, int arg){ + put_user(keyinfo, buffer); + keyinfo = 0; + return 1; + } + static int triokb_select(struct inode *inode, struct file *file, int sel_type, select_table *wait){ + if (sel_type == SEL_IN) { + if (!keyinfo){ + select_wait(&user_queue, wait); + return 0; + } + } + return 1; + } + static int triokb_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ + switch(cmd){ + case TRIOKB_PIOMASK: + kb_mask = *(struct triokb_piomask *)arg; + if(!calc_tables()){ + return -EINVAL; + } + key_cnt = 0; + if(kb_mask.pra_mask) + trioport_out(kb_handler.pa, kb_mask.pra_mask); + if(kb_mask.prb_mask) + trioport_out(kb_handler.pb, kb_mask.prb_mask); + queue_task_irq_off(&kb_poll, &tq_timer); + break; + default: + return -EINVAL; + } + return 0; + } + static int triokb_open(struct inode *inode, struct file *file) + { + return 0; + } + static void triokb_release(struct inode *inode, struct file *file) + { + } + static struct file_operations triokb_fops = { + NULL, + triokb_read, + NULL, + NULL, /* No readdir */ + triokb_select, + triokb_ioctl, + NULL, /* No mmap */ + triokb_open, + triokb_release + }; + static struct miscdevice triokb_dev= + { + TRIOKB_MINOR, + "triokb", + &triokb_fops + }; + + static int triokb_reinit(void){ + kb_poll.routine = kbpoll; + kb_poll.data = 0; + kb_handler.interrupt = NULL; + if( pio_hook_driver(&kb_handler) < 0){ + printk("Kb driver not initialized\n"); + return -1; + } + return 0; + } + int triokb_init(void){ + if(triokb_reinit() < 0) + printk("Kb driver not registered\n"); + else + misc_register(&triokb_dev); + return 0; + } + Index: AplioTRIO/linux/arch/armnommu/drivers/char/triopio.h diff -c /dev/null AplioTRIO/linux/arch/armnommu/drivers/char/triopio.h:1.2 *** /dev/null Fri Jan 28 16:54:03 2000 --- AplioTRIO/linux/arch/armnommu/drivers/char/triopio.h Thu Jan 27 17:58:17 2000 *************** *** 0 **** --- 1,30 ---- + struct trioport{ + struct pio_regs *base; + u_32 pio; + u_32 pout; + u_32 irq; + u_32 irq_nb; + u_32 pdout; + u_32 pdin; + u_32 inmask; + u_32 outmask; + }; + struct pio_handler{ + int id; + int (*interrupt)(struct trioport *, u_32); + int priority; + u_32 pa_mask; + u_32 pb_mask; + struct trioport *pa; + struct trioport *pb; + struct pio_handler *prev; + struct pio_handler *next; + }; + int pio_hook_driver(struct pio_handler* handler); + int pio_remove_driver(struct pio_handler *handler); + + void trioport_out(struct trioport* p, u_32 value); + u_32 trioport_get_in(struct trioport *p); + int trioport_set_out(struct trioport *p, u_32 mask, u_32 value); + + Index: AplioTRIO/linux/arch/armnommu/drivers/char/trioport.c diff -c /dev/null AplioTRIO/linux/arch/armnommu/drivers/char/trioport.c:1.5 *** /dev/null Fri Jan 28 16:54:03 2000 --- AplioTRIO/linux/arch/armnommu/drivers/char/trioport.c Thu Jan 27 17:58:10 2000 *************** *** 0 **** --- 1,350 ---- + /* + * + */ + + #define TRIOPORT_VERSION "0.01" + + /* + */ + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + #include + #include "triopio.h" + /* + * We sponge a minor off of the misc major. No need slurping + * up another valuable major dev number for this. + */ + + #define TRIOPORTA_MINOR 175 + #define TRIOPORTB_MINOR 176 + + static struct trioport porta, portb; + static struct trioport* ports[2]; + + static struct tq_struct port_poll; + static struct wait_queue *user_queue = NULL; + + extern int setup_arm_irq(int, struct irqaction *); + + static void trioport_io(struct trioport* p, u_32 value); + static void trioport_irq_on(struct trioport* p, u_32 value); + static void trioport_irq_off(struct trioport* p, u_32 value); + static void trioports_irqs_off(void); + + static struct pio_handler *pio_head; + static int handler_id; + static int trioports_initialized=0; + + int pio_hook_driver(struct pio_handler *handler){ + struct pio_handler *p; + unsigned long flags; + if(!trioports_initialized){ + return -1; + } + if (!handler->interrupt){ + // asks only for PIO addresses, no interrupts required + handler->pa = &porta; + handler->pb = &portb; + return 0; + } + save_flags_cli(flags); + if (pio_head == NULL){ + pio_head = handler; + handler->next = NULL; + handler->prev = NULL; + handler_id = 1; + handler->pa = &porta; + handler->pb = &portb; + return handler_id; + } + p = pio_head->next; + while(p->priority > handler->priority){ + if(p->next){ + p = p->next; + }else{ + break; + } + } + if(p->next){ + handler->prev = p->prev; + handler->next = p; + p->prev->next = handler; + }else{ + p->next = handler; + handler->prev = p; + handler->next = NULL; + } + if(handler->pa_mask) + trioport_irq_on(&porta, handler->pa_mask); + if(handler->pb_mask) + trioport_irq_on(&portb, handler->pb_mask); + + handler->pa = &porta; + handler->pb = &portb; + + restore_flags(flags); + return (++handler_id); + } + int pio_remove_driver(struct pio_handler *handler){ + struct pio_handler *p; + unsigned long flags; + save_flags_cli(flags); + p = pio_head; + while(p->id != handler->id){ + if(p->next) + p = p->next; + else + break; + } + if(p->next){ + p->prev->next = p->next; + p->next->prev = p->prev; + }else{ + // end of queue + if(p->id == handler->id){ + p->prev->next = NULL; + }else{ + // not found + return -1; + } + } + if(handler->pa_mask) + trioport_irq_off(&porta, handler->pa_mask); + if(handler->pb_mask) + trioport_irq_off(&portb, handler->pb_mask); + + restore_flags(flags); + return 0; + } + + static int trioport_read(struct inode *inode, struct file *file, char *buffer, int arg){ + struct trioport *p; + int minor; + u_32 value; + if (arg < sizeof(u_32)) + return 0; + minor = MINOR(inode->i_rdev); + p = (minor == TRIOPORTA_MINOR)?&porta:&portb; + value = trioport_get_in(p); + put_user(value, buffer); + return (sizeof(value)); + } + u_32 trioport_get_in(struct trioport *p){ + u_32 value; + unsigned long flags; + save_flags_cli(flags); + value = (p->base->odsr & p->outmask) || (p->base->pdsr & p->inmask); + restore_flags(flags); + return value; + } + static int trioport_write(struct inode *inode, struct file *file, const char *buffer, int arg){ + struct trioport *p; + int minor; + u_32 value,mask; + if (arg < 2*sizeof(u_32)) + return 0; + minor = MINOR(inode->i_rdev); + p = (minor == TRIOPORTA_MINOR)?&porta:&portb; + + mask = *((u_32*)buffer); + value = *((u_32*)buffer+1); + trioport_set_out(p, mask, value); + return 2*sizeof(u_32); + } + int trioport_set_out(struct trioport *p, u_32 mask, u_32 value){ + u_32 status; + unsigned long flags; + save_flags_cli(flags); + p->base->sodr = value & mask & p->outmask; + p->base->codr = ~value & mask & p->outmask; + status = p->base->odsr; + restore_flags(flags); + return status; + } + void trioport_out(struct trioport* p, u_32 value){ + unsigned long flags; + save_flags_cli(flags); + p->base->oer = p->pout = value; + p->base->odr = ~value; + p->outmask = p->pio & p->base->osr; + p->inmask = p->pio & ~p->base->osr; + restore_flags(flags); + } + static void trioport_io(struct trioport* p, u_32 value){ + unsigned long flags; + save_flags_cli(flags); + p->base->per = value; + p->base->pdr = ~value; + p->pio = p->base->psr; + restore_flags(flags); + } + static void trioport_irq_on(struct trioport* p, u_32 value){ + p->base->ier = value & p->inmask; + p->irq = p->base->imr; + (p->irq)?unmask_irq(p->irq_nb):mask_irq(p->irq_nb); + } + static void trioport_irq_off(struct trioport* p, u_32 value){ + p->base->idr = value & p->inmask; + p->irq = p->base->imr; + (p->irq)?unmask_irq(p->irq_nb):mask_irq(p->irq_nb); + } + static void trioports_irqs_off(){ + unsigned long flags; + save_flags_cli(flags); + porta.base->idr = 0xFFFFFFFF; + porta.irq = porta.base->imr; + mask_irq(porta.irq_nb); + portb.base->idr = 0xFFFFFFFF; + portb.irq = portb.base->imr; + mask_irq(portb.irq_nb); + restore_flags(flags); + } + static void pio_interrupt(struct trioport *p){ + u_32 changed; + struct pio_handler *ph; + if((ph=pio_head)){ + changed = p->pdin ^ p->base->pdsr; + while(ph){ + if(ph->interrupt(p, changed)){ + break; + } + ph = ph->next; + } + } + p->pdin = p->base->pdsr; + } + static void pio_interrupta(int irq, void *dev_id, struct pt_regs * regs){ + pio_interrupt(&porta); + } + static void pio_interruptb(int irq, void *dev_id, struct pt_regs * regs){ + pio_interrupt(&portb); + } + static int trioport_ioctl(struct inode *inode, struct file *file, unsigned int cmd, + unsigned long arg) + { + struct trioport *p; + int minor = MINOR(inode->i_rdev); + p = (minor == TRIOPORTA_MINOR)?&porta:&portb; + switch (cmd) { + + case TRIOPORT_IO: + trioport_io(p, arg); + break; + + case TRIOPORT_CTRL: + trioport_io(p, ~arg); + break; + + case TRIOPORT_OUT: + trioport_out(p, arg); + break; + + case TRIOPORT_IRQ_ON: + trioport_irq_on(p, arg); + break; + + case TRIOPORT_IRQ_OFF: + trioport_irq_off(p, arg); + break; + + default: + return -EINVAL; + } + return 0; + } + + static int trioport_open(struct inode *inode, struct file *file) + { + return 0; + } + static void trioport_release(struct inode *inode, struct file *file) + { + } + static struct file_operations trioport_fops = { + NULL, + trioport_read, + trioport_write, + NULL, /* No readdir */ + NULL, + trioport_ioctl, + NULL, /* No mmap */ + trioport_open, + trioport_release + }; + static struct miscdevice trioporta_dev= + { + TRIOPORTA_MINOR, + "trioporta", + &trioport_fops + }; + static struct miscdevice trioportb_dev= + { + TRIOPORTB_MINOR, + "trioportb", + &trioport_fops + }; + + static struct irqaction irq_pioa = { pio_interrupta, 0, 0, "pioa", NULL, NULL}; + static struct irqaction irq_piob = { pio_interruptb, 0, 0, "piob", NULL, NULL}; + + static void interrupts_init(void) + { + setup_arm_irq(IRQ_PIOA, &irq_pioa); + setup_arm_irq(IRQ_PIOB, &irq_piob); + } + int trioport_init(void) + { + porta.base = (struct pio_regs *)PIOA_BASE; + portb.base = (struct pio_regs *)PIOB_BASE; + porta.irq_nb = AIC_PIOA; + portb.irq_nb = AIC_PIOB; + ports[0] = &porta; + ports[1] = &portb; + + /* set irqs off, the default PIO config should be already set by boot software */ + trioports_irqs_off(); + interrupts_init(); + + /* read actual values, set by previous procedures */ + + porta.pio = porta.base->psr; + portb.pio = portb.base->psr; + + porta.pout = porta.base->odsr; + portb.pout = portb.base->odsr; + + porta.outmask = porta.pout & porta.pio; + portb.outmask = portb.pout & portb.pio; + + porta.inmask = ~porta.pout & porta.pio; + portb.inmask = ~portb.pout & portb.pio; + + pio_head = NULL; + handler_id = 0; + + misc_register(&trioporta_dev); + misc_register(&trioportb_dev); + trioports_initialized = 1; + return 0; + } + Index: AplioTRIO/linux/arch/armnommu/drivers/char/trioserial.c diff -c AplioTRIO/linux/arch/armnommu/drivers/char/trioserial.c:1.7 AplioTRIO/linux/arch/armnommu/drivers/char/trioserial.c:1.9 *** AplioTRIO/linux/arch/armnommu/drivers/char/trioserial.c:1.7 Mon Nov 29 11:41:36 1999 --- AplioTRIO/linux/arch/armnommu/drivers/char/trioserial.c Wed Jan 12 17:23:14 2000 *************** *** 74,79 **** --- 74,80 ---- struct tq_struct serialpoll; struct tty_driver serial_driver, callout_driver; + struct tty_driver serial_driver2, callout_driver2; static int serial_refcount; /* serial subtype definitions */ *************** *** 385,400 **** if (tty->flip.count >= TTY_FLIPBUF_SIZE) queue_task_irq_off(&tty->flip.tqueue, &tq_timer); ! tty->flip.count++; if(status & US_PARE) ! *tty->flip.flag_buf_ptr++ = TTY_PARITY; else if(status & US_OVRE) ! *tty->flip.flag_buf_ptr++ = TTY_OVERRUN; else if(status & US_FRAME) ! *tty->flip.flag_buf_ptr++ = TTY_FRAME; ! else ! *tty->flip.flag_buf_ptr++ = 0; /* XXX */ ! *tty->flip.char_buf_ptr++ = ch; queue_task_irq_off(&tty->flip.tqueue, &tq_timer); --- 386,404 ---- if (tty->flip.count >= TTY_FLIPBUF_SIZE) queue_task_irq_off(&tty->flip.tqueue, &tq_timer); ! ! memset(tty->flip.flag_buf_ptr, 0, count); ! memcpy(tty->flip.char_buf_ptr, info->rx_buf, count); ! tty->flip.char_buf_ptr += count; ! if(status & US_PARE) ! *(tty->flip.flag_buf_ptr-1) = TTY_PARITY; else if(status & US_OVRE) ! *(tty->flip.flag_buf_ptr-1) = TTY_OVERRUN; else if(status & US_FRAME) ! *(tty->flip.flag_buf_ptr-1) = TTY_FRAME; ! ! tty->flip.count += count; queue_task_irq_off(&tty->flip.tqueue, &tq_timer); *************** *** 790,795 **** --- 794,800 ---- /* * Fair output driver allows a process to speak. */ + #if 0 static void rs_fair_output( struct trio_serial *info) { int left; /* Output no more than that */ *************** *** 819,825 **** restore_flags(flags); return; } ! /* * trio_console_print is registered for printk. */ --- 824,830 ---- restore_flags(flags); return; } ! #endif /* * trio_console_print is registered for printk. */ *************** *** 987,993 **** /* Send char */ wait_EOT(info->uart); xmit_string(info, &info->xmit_buf[info->xmit_tail], info->xmit_cnt); ! info->xmit_tail = info->xmit_tail & (SERIAL_XMIT_SIZE-1); info->xmit_cnt=0; } } --- 992,998 ---- /* Send char */ wait_EOT(info->uart); xmit_string(info, &info->xmit_buf[info->xmit_tail], info->xmit_cnt); ! info->xmit_tail = (info->xmit_tail + info->xmit_cnt) & (SERIAL_XMIT_SIZE-1); info->xmit_cnt=0; } } *************** *** 1696,1702 **** void interrupts_init(void) { setup_arm_irq(IRQ_USARTA, &irq_usarta); ! setup_arm_irq(IRQ_USARTB, &irq_usartb); } /* rs_init inits the driver */ --- 1701,1707 ---- void interrupts_init(void) { setup_arm_irq(IRQ_USARTA, &irq_usarta); ! // setup_arm_irq(IRQ_USARTB, &irq_usartb); } /* rs_init inits the driver */ *************** *** 1761,1794 **** save_flags(flags); cli(); i=0; ! while(imagic = SERIAL_MAGIC; ! info->uart = uarts[i]; ! info->tty = 0; ! info->irqmask = (i)?AIC_UB:AIC_UA; ! info->irq = (i)?IRQ_USARTB:IRQ_USARTA; ! info->port = i+1; ! set_ints_mode(0,info); ! info->custom_divisor = 16; ! info->close_delay = 50; ! info->closing_wait = 3000; ! info->x_char = 0; ! info->event = 0; ! info->count = 0; ! info->blocked_open = 0; ! info->tqueue.routine = do_softint; ! info->tqueue.data = info; ! info->tqueue_hangup.routine = do_serial_hangup; ! info->tqueue_hangup.data = info; ! info->callout_termios =callout_driver.init_termios; ! info->normal_termios = serial_driver.init_termios; ! info->open_wait = 0; ! info->close_wait = 0; ! info->line = 0; ! info->is_cons = (i)?0:1; /* Means shortcuts work */ ! i++; ! } interrupts_init(); restore_flags(flags); // hack to do polling --- 1766,1797 ---- save_flags(flags); cli(); i=0; ! info = &trio_info[i]; ! info->magic = SERIAL_MAGIC; ! info->uart = uarts[i]; ! info->tty = 0; ! info->irqmask = (i)?AIC_UB:AIC_UA; ! info->irq = (i)?IRQ_USARTB:IRQ_USARTA; ! info->port = i+1; ! set_ints_mode(0,info); ! info->custom_divisor = 16; ! info->close_delay = 50; ! info->closing_wait = 3000; ! info->x_char = 0; ! info->event = 0; ! info->count = 0; ! info->blocked_open = 0; ! info->tqueue.routine = do_softint; ! info->tqueue.data = info; ! info->tqueue_hangup.routine = do_serial_hangup; ! info->tqueue_hangup.data = info; ! info->callout_termios =callout_driver.init_termios; ! info->normal_termios = serial_driver.init_termios; ! info->open_wait = 0; ! info->close_wait = 0; ! info->line = 0; ! info->is_cons = (i)?0:1; /* Means shortcuts work */ ! interrupts_init(); restore_flags(flags); // hack to do polling Index: AplioTRIO/linux/arch/armnommu/drivers/char/tty_io.c diff -c AplioTRIO/linux/arch/armnommu/drivers/char/tty_io.c:1.4 AplioTRIO/linux/arch/armnommu/drivers/char/tty_io.c:1.5 *** AplioTRIO/linux/arch/armnommu/drivers/char/tty_io.c:1.4 Tue Nov 30 10:58:12 1999 --- AplioTRIO/linux/arch/armnommu/drivers/char/tty_io.c Wed Dec 29 15:32:45 1999 *************** *** 1186,1195 **** --- 1186,1197 ---- device = current->tty->device; /* noctty = 1; */ } + #ifdef CONFIG_CONSOLE if (device == CONSOLE_DEV) { device = MKDEV(TTY_MAJOR, vtdata.fgconsole->num); noctty = 1; } + #endif minor = MINOR(device); retval = init_dev(device, &tty); *************** *** 1548,1553 **** --- 1550,1556 ---- printk("Deprecated TIOCLINUX (1) ioctl\n"); return do_get_ps_info(arg); #endif + #ifdef CONFIG_CONSOLE case 2: return set_selection(arg, tty); case 3: *************** *** 1558,1563 **** --- 1561,1567 ---- case 5: return sel_loadlut(arg); case 6: + /* * Make it possible to react to Shift+Mousebutton. * Note that 'shift_state' is an undocumented *************** *** 1578,1583 **** --- 1582,1588 ---- /* case 10: set_vesa_blanking(arg); return 0;*/ + #endif /* CONFIG_CONSOLE */ case 11: /* set kmsg redirect */ if (!suser()) return -EPERM; *************** *** 1587,1594 **** --- 1592,1602 ---- return retval; kmsg_redirect = get_user((char *)arg+1); return 0; + #ifdef CONFIG_CONSOLE case 12: /* get fg console */ + return vtdata.fgconsole->num; + #endif default: return -EINVAL; } *************** *** 1847,1854 **** { if (sizeof(struct tty_struct) > PAGE_SIZE) panic("size of tty structure > PAGE_SIZE!"); - vt_post_init (); /* * dev_tty_driver and dev_console_driver are actually magic * devices which get redirected at open time. Nevertheless, --- 1855,1865 ---- { if (sizeof(struct tty_struct) > PAGE_SIZE) panic("size of tty structure > PAGE_SIZE!"); + #ifdef CONFIG_CONSOLE + vt_post_init (); + #endif + /* * dev_tty_driver and dev_console_driver are actually magic * devices which get redirected at open time. Nevertheless, *************** *** 1873,1879 **** if (tty_register_driver(&dev_console_driver)) panic("Couldn't register /dev/console driver\n"); ! #ifndef CONFIG_ARCH_EBSA110 kbd_init(); #endif #ifdef CONFIG_SERIAL --- 1884,1890 ---- if (tty_register_driver(&dev_console_driver)) panic("Couldn't register /dev/console driver\n"); ! #ifdef CONFIG_CONSOLE kbd_init(); #endif #ifdef CONFIG_SERIAL *************** *** 1883,1889 **** --- 1894,1902 ---- rs_trio_init(); #endif pty_init(); + #ifdef CONFIG_CONSOLE vcs_init(); + #endif return 0; } Index: AplioTRIO/linux/arch/armnommu/drivers/net/Space.c diff -c AplioTRIO/linux/arch/armnommu/drivers/net/Space.c:1.2 AplioTRIO/linux/arch/armnommu/drivers/net/Space.c:1.3 *** AplioTRIO/linux/arch/armnommu/drivers/net/Space.c:1.2 Tue Nov 23 14:17:38 1999 --- AplioTRIO/linux/arch/armnommu/drivers/net/Space.c Wed Jan 12 17:07:09 2000 *************** *** 59,65 **** #ifdef CONFIG_ETHERC && etherc_probe (dev) #endif ! #ifdef CONFIG_TRIO_CS6800 && cs89x0_probe (dev) #endif #ifdef CONFIG_ETHER3 --- 59,65 ---- #ifdef CONFIG_ETHERC && etherc_probe (dev) #endif ! #ifdef CONFIG_TRIO_CS8900 && cs89x0_probe (dev) #endif #ifdef CONFIG_ETHER3 *************** *** 102,108 **** "eth2" , 0x0, 0x0, 0x0, 0x0, 0xffe0 , 0 , 0, 0, 0, ð3_dev , ethif_probe }; static struct device eth1_dev = { ! "eth1" , 0x0, 0x0, 0x0, 0x0, ETH1_ADDR, ETH1_IRQ, 0, 0, 0, ð2_dev , ethif_probe }; static struct device eth0_dev = { "eth0" , 0x0, 0x0, 0x0, 0x0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, ð1_dev , ethif_probe }; --- 102,108 ---- "eth2" , 0x0, 0x0, 0x0, 0x0, 0xffe0 , 0 , 0, 0, 0, ð3_dev , ethif_probe }; static struct device eth1_dev = { ! "eth1" , 0x0, 0x0, 0x0, 0x0, 0xffe0 , 0 , 0, 0, 0, ð2_dev , ethif_probe }; static struct device eth0_dev = { "eth0" , 0x0, 0x0, 0x0, 0x0, ETH0_ADDR, ETH0_IRQ, 0, 0, 0, ð1_dev , ethif_probe }; Index: AplioTRIO/linux/arch/armnommu/drivers/net/trioCS8900.c diff -c AplioTRIO/linux/arch/armnommu/drivers/net/trioCS8900.c:1.1 AplioTRIO/linux/arch/armnommu/drivers/net/trioCS8900.c:1.2 *** AplioTRIO/linux/arch/armnommu/drivers/net/trioCS8900.c:1.1 Tue Nov 23 14:16:58 1999 --- AplioTRIO/linux/arch/armnommu/drivers/net/trioCS8900.c Wed Jan 12 17:06:53 2000 *************** *** 37,43 **** /* use 0 for production, 1 for verification, >2 for debug */ #ifndef NET_DEBUG ! #define NET_DEBUG 2 #endif /* ======================= end of configuration ======================= */ --- 37,43 ---- /* use 0 for production, 1 for verification, >2 for debug */ #ifndef NET_DEBUG ! #define NET_DEBUG 3 #endif /* ======================= end of configuration ======================= */ *************** *** 139,170 **** return cs89x0_probe1(dev, base_addr); } ! int inline readreg(struct device *dev, int portno) { outw(portno, dev->base_addr + ADD_PORT); return inw(dev->base_addr + DATA_PORT); } ! void inline writereg(struct device *dev, int portno, int value) { outw(portno, dev->base_addr + ADD_PORT); outw(value, dev->base_addr + DATA_PORT); } ! int inline readword(struct device *dev, int portno) { return inw(dev->base_addr + portno); } ! void inline writeword(struct device *dev, int portno, int value) { outw(value, dev->base_addr + portno); } /* This is the real probe routine. */ static int cs89x0_probe1(struct device *dev, int ioaddr) --- 139,171 ---- return cs89x0_probe1(dev, base_addr); } ! static int inline readreg(struct device *dev, int portno) { outw(portno, dev->base_addr + ADD_PORT); return inw(dev->base_addr + DATA_PORT); } ! static void inline writereg(struct device *dev, int portno, int value) { outw(portno, dev->base_addr + ADD_PORT); outw(value, dev->base_addr + DATA_PORT); } ! static int inline readword(struct device *dev, int portno) { return inw(dev->base_addr + portno); } ! static void inline writeword(struct device *dev, int portno, int value) { outw(value, dev->base_addr + portno); } + /* This is the real probe routine. */ static int cs89x0_probe1(struct device *dev, int ioaddr) *************** *** 172,178 **** --- 173,184 ---- struct net_local *lp; static unsigned version_printed = 0; unsigned rev_type = 0; + unsigned chip_id=0; + int i; + /* Change SBHE connected to A0 before any access to the chip. + This forces 16 bit mode. + */ irq2dev_map[0] = dev; /* Initialize the device structure. */ *************** *** 183,188 **** --- 189,206 ---- dev->base_addr = ioaddr; lp = (struct net_local *)dev->priv; + // dummy access to switch from byte mode + chip_id = readword(dev, ADD_PORT); + printk("\nCS8900 Addr=%x\n", chip_id); + + // hack + writereg(dev, PP_CS8900_ISAINT, 0); + + chip_id = readreg(dev, PP_ChipID); + printk("\nChipId=%x\n", chip_id); + chip_id = readreg(dev, PP_ISAIOB); + printk("\nIOAddr=%x\n", chip_id); + if (readreg(dev, PP_ChipID) != CHIP_EISA_ID_SIG) { printk("cs89x0.c: No CrystalLan device found.\n"); return ENODEV; *************** *** 244,250 **** /* print the ethernet address. */ for (i = 0; i < ETH_ALEN; i++) printk(" %2.2x", dev->dev_addr[i]); - #endif /* not CONFIG_TRIO */ #ifdef FIXME --- 262,267 ---- *************** *** 379,385 **** writereg(dev, PP_BusCTL, 0); /* ints off! */ #ifdef CONFIG_TRIO_CS8900 ! setup_arm_irq(IRQ_EXT0, &irq_cs8900); #else *(volatile unsigned short *)0xfffff302 |= 0x0080; /* +ve pol irq */ if (request_irq(IRQ_MACHSPEC | 20, --- 396,404 ---- writereg(dev, PP_BusCTL, 0); /* ints off! */ #ifdef CONFIG_TRIO_CS8900 ! if(setup_arm_irq(IRQ_EXT0, &irq_cs8900)){ ! printk("CS8900 setup irq failed\n"); ! } #else *(volatile unsigned short *)0xfffff302 |= 0x0080; /* +ve pol irq */ if (request_irq(IRQ_MACHSPEC | 20, *************** *** 387,394 **** IRQ_FLG_STD, "CrystalLAN_cs8900a", NULL)) panic("Unable to attach cs8900 intr\n"); - #endif /* set the Ethernet address */ set_mac_address(dev, dev->dev_addr); --- 406,413 ---- IRQ_FLG_STD, "CrystalLAN_cs8900a", NULL)) panic("Unable to attach cs8900 intr\n"); + #endif /* set the Ethernet address */ set_mac_address(dev, dev->dev_addr); *************** *** 552,558 **** struct device *dev = (struct device *)(irq2dev_map[/* FIXME */0]); struct net_local *lp; int ioaddr, status; ! dev = irq2dev_map[0]; if (dev == NULL) { printk ("net_interrupt(): irq %d for unknown device.\n", irq); --- 571,577 ---- struct device *dev = (struct device *)(irq2dev_map[/* FIXME */0]); struct net_local *lp; int ioaddr, status; ! dev = irq2dev_map[0]; if (dev == NULL) { printk ("net_interrupt(): irq %d for unknown device.\n", irq); *************** *** 625,630 **** --- 644,650 ---- int ioaddr = dev->base_addr; struct sk_buff *skb; int status, length; + int i; status = inw(ioaddr + RX_FRAME_PORT); length = inw(ioaddr + RX_FRAME_PORT); *************** *** 640,663 **** } /* Malloc up new buffer. */ ! skb = alloc_skb(length, GFP_ATOMIC); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); lp->stats.rx_dropped++; return; } skb->len = length; skb->dev = dev; ! insw(ioaddr + RX_FRAME_PORT, skb->data, length >> 1); if (length & 1) skb->data[length-1] = inw(ioaddr + RX_FRAME_PORT); if (net_debug > 3)printk("%s: received %d byte packet of type %x\n", dev->name, length, (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]); - skb->protocol=eth_type_trans(skb,dev); netif_rx(skb); lp->stats.rx_packets++; return; --- 660,691 ---- } /* Malloc up new buffer. */ ! skb = alloc_skb(length+2, GFP_ATOMIC); if (skb == NULL) { printk("%s: Memory squeeze, dropping packet.\n", dev->name); lp->stats.rx_dropped++; return; } + skb_reserve(skb, 2); skb->len = length; skb->dev = dev; ! insw(ioaddr + RX_FRAME_PORT, skb->data, length >> 1); if (length & 1) skb->data[length-1] = inw(ioaddr + RX_FRAME_PORT); if (net_debug > 3)printk("%s: received %d byte packet of type %x\n", dev->name, length, (skb->data[ETH_ALEN+ETH_ALEN] << 8) | skb->data[ETH_ALEN+ETH_ALEN+1]); + if(net_debug > 4){ + for(i=0;i<20;i++){ + printk("%.2x ",*(skb->data + i)); + } + printk("\n"); + } + skb->protocol=eth_type_trans(skb,dev); + netif_rx(skb); lp->stats.rx_packets++; return; Index: AplioTRIO/linux/arch/armnommu/kernel/head-arm-aplio.S diff -c AplioTRIO/linux/arch/armnommu/kernel/head-arm-aplio.S:1.4 AplioTRIO/linux/arch/armnommu/kernel/head-arm-aplio.S:1.5 *** AplioTRIO/linux/arch/armnommu/kernel/head-arm-aplio.S:1.4 Wed Nov 24 20:01:02 1999 --- AplioTRIO/linux/arch/armnommu/kernel/head-arm-aplio.S Mon Dec 27 20:21:06 1999 *************** *** 34,40 **** _entry: __stext: __entry: ! bl config_timer1 #if 0 --- 34,40 ---- _entry: __stext: __entry: ! bl config_aic bl config_timer1 #if 0 *************** *** 268,273 **** --- 268,284 ---- .long 0xFF00C034 PIOB_COD_Value: .long 0xFFFFFFFF + + + + /* + configure AIC, disable all interrupt sources + */ + config_aic: + ldr r1,=AIC_IDCR + ldr r2,=0xFFFFFFFF + str r2, [r1] + mov pc, lr /* ;------------------------------------------------------------------------------ Index: AplioTRIO/linux/arch/armnommu/kernel/setup.c diff -c AplioTRIO/linux/arch/armnommu/kernel/setup.c:1.4 AplioTRIO/linux/arch/armnommu/kernel/setup.c:1.6 *** AplioTRIO/linux/arch/armnommu/kernel/setup.c:1.4 Tue Dec 14 10:30:04 1999 --- AplioTRIO/linux/arch/armnommu/kernel/setup.c Wed Dec 29 15:32:46 1999 *************** *** 69,75 **** ! #ifndef CONFIG_ARCH_TRIO static struct param_struct *params = (struct param_struct *) PARAMS_BASE; #else --- 69,75 ---- ! #if defined( CONFIG_ARCH_TRIO) static struct param_struct *params = (struct param_struct *) PARAMS_BASE; #else *************** *** 201,208 **** --- 201,210 ---- check_ioeb_present (); processor._proc_init (); + #ifdef CONFIG_CONSOLE bytes_per_char_h = params->u1.s.bytes_per_char_h; bytes_per_char_v = params->u1.s.bytes_per_char_v; + #endif from = params->commandline; ROOT_DEV = to_kdev_t (params->u1.s.rootdev); ORIG_X = params->u1.s.video_x; Index: AplioTRIO/linux/arch/armnommu/lib/segment.S diff -c AplioTRIO/linux/arch/armnommu/lib/segment.S:1.1.1.1 AplioTRIO/linux/arch/armnommu/lib/segment.S:1.2 *** AplioTRIO/linux/arch/armnommu/lib/segment.S:1.1.1.1 Mon Nov 15 14:42:37 1999 --- AplioTRIO/linux/arch/armnommu/lib/segment.S Mon Dec 27 20:21:08 1999 *************** *** 32,38 **** sub r2, r2, ip b Lmtfs_dest_aligned ! .global ___memcpy_tofs,__memcpy_tofs __memcpy_tofs: ___memcpy_tofs: cmp r0, #0x02000000 @ PHYS check --- 32,40 ---- sub r2, r2, ip b Lmtfs_dest_aligned ! .global ___memcpy_tofs,__memcpy_tofs,_memcpy_tofs,memcpy_tofs ! memcpy_tofs: ! _memcpy_tofs: __memcpy_tofs: ___memcpy_tofs: cmp r0, #0x02000000 @ PHYS check Index: AplioTRIO/linux/drivers/block/blkmem.c diff -c AplioTRIO/linux/drivers/block/blkmem.c:1.1.1.1 AplioTRIO/linux/drivers/block/blkmem.c:1.2 *** AplioTRIO/linux/drivers/block/blkmem.c:1.1.1.1 Mon Nov 15 14:41:46 1999 --- AplioTRIO/linux/drivers/block/blkmem.c Mon Dec 27 20:21:09 1999 *************** *** 40,54 **** #include #include - #include #define TRUE (1) #define FALSE (0) #if defined( CONFIG_M68328 ) || defined ( CONFIG_M68EZ328 ) #define CAT_ROMARRAY #endif /* Simple romfs, at internal, cat on the end of kernel, or seperate fixed adderess romfs. */ #ifdef INTERNAL_ROMARRAY --- 40,60 ---- #include #include #define TRUE (1) #define FALSE (0) #if defined( CONFIG_M68328 ) || defined ( CONFIG_M68EZ328 ) + #include + #define CAT_ROMARRAY #endif + #ifdef CONFIG_ARCH_TRIO + #define FIXED_ROMARRAY (char*)(3512*1024) + #endif + + /* Simple romfs, at internal, cat on the end of kernel, or seperate fixed adderess romfs. */ #ifdef INTERNAL_ROMARRAY *************** *** 118,124 **** #endif #ifdef FIXED_ROMARRAY ! {romarray, -1} #endif #ifdef CONFIG_SHGLCORE --- 124,130 ---- #endif #ifdef FIXED_ROMARRAY ! {0, FIXED_ROMARRAY, -1} #endif #ifdef CONFIG_SHGLCORE *************** *** 139,144 **** --- 145,151 ---- arena[2].length = (unsigned long)rom_length; #endif + }; #define arenas (sizeof(arena) / sizeof(struct arena_t)) *************** *** 1097,1103 **** NULL, /* fasync */ NULL, /* check media change */ NULL, /* revalidate */ ! blkmem_romptr, /* romptr */ }; int --- 1104,1114 ---- NULL, /* fasync */ NULL, /* check media change */ NULL, /* revalidate */ ! #ifdef MAGIC_ROM_PTR ! blkmem_romptr /* romptr */ ! #else ! NULL ! #endif }; int Index: AplioTRIO/linux/fs/binfmt_flat.c diff -c AplioTRIO/linux/fs/binfmt_flat.c:1.1.1.1 AplioTRIO/linux/fs/binfmt_flat.c:1.2 *** AplioTRIO/linux/fs/binfmt_flat.c:1.1.1.1 Mon Nov 15 14:41:03 1999 --- AplioTRIO/linux/fs/binfmt_flat.c Fri Jan 28 16:19:58 2000 *************** *** 40,47 **** #include #include - #undef DEBUG static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs); extern void dump_thread(struct pt_regs *, struct user *); --- 40,51 ---- #include #include + #include + + + #define DEBUG + static int load_flat_binary(struct linux_binprm *, struct pt_regs * regs); extern void dump_thread(struct pt_regs *, struct user *); *************** *** 124,130 **** envp = sp; sp -= argc+1; argv = sp; ! #if defined(__i386__) || defined(__mc68000__) put_user(envp,--sp); put_user(argv,--sp); #endif --- 128,134 ---- envp = sp; sp -= argc+1; argv = sp; ! #if defined(__i386__) || defined(__mc68000__) || defined(__arm__) put_user(envp,--sp); put_user(argv,--sp); #endif *************** *** 211,218 **** hdr = (struct flat_hdr*)bprm->buf; ! if (strncmp(hdr->magic, "bFLT", 4) || (hdr->rev != 2)) { ! printk("bad magic/rev (%ld, need %d)\n", hdr->rev, 2); return -ENOEXEC; } --- 215,222 ---- hdr = (struct flat_hdr*)bprm->buf; ! if (strncmp(hdr->magic, "bFLT", 4) || (hdr->rev != ntohl(2))) { ! printk("bad magic/rev (%ld, need %d)\n", ntohl(hdr->rev), 2); return -ENOEXEC; } *************** *** 227,236 **** /* OK, This is the point of no return */ ! code_len = hdr->data_start; ! data_len = hdr->data_end - hdr->data_start; ! bss_len = hdr->bss_end - hdr->data_end; ! stack_len = hdr->stack_size; /* Make room on stack for arguments & environment */ stack_len += strlen(bprm->filename) + 1; --- 231,240 ---- /* OK, This is the point of no return */ ! code_len = ntohl(hdr->data_start); ! data_len = ntohl(hdr->data_end) - code_len; ! bss_len = ntohl(hdr->bss_end) - ntohl(hdr->data_end); ! stack_len = ntohl(hdr->stack_size); /* Make room on stack for arguments & environment */ stack_len += strlen(bprm->filename) + 1; *************** *** 244,250 **** error = do_mmap(file, 0, code_len + data_len + bss_len + stack_len, ! PROT_READ|PROT_EXEC | ((hdr->flags & FLAT_FLAG_RAM) ? PROT_WRITE : 0), 0 /* MAP_* */, 0); --- 248,254 ---- error = do_mmap(file, 0, code_len + data_len + bss_len + stack_len, ! PROT_READ|PROT_EXEC | ((hdr->flags & htonl(FLAT_FLAG_RAM)) ? PROT_WRITE : 0), 0 /* MAP_* */, 0); *************** *** 259,266 **** #endif current->mm->executable = 0; ! ! if (is_in_rom(error)) { unsigned long result; #ifdef DEBUG printk("BINFMT_FLAT: ROM mapping of file\n"); --- 263,272 ---- #endif current->mm->executable = 0; ! #ifndef MAGIC_ROMPTR ! #define is_in_rom(x) 0 ! #endif ! if (is_in_rom(error)) { unsigned long result; #ifdef DEBUG printk("BINFMT_FLAT: ROM mapping of file\n"); *************** *** 282,288 **** /*printk("Reading data from %d-%d to %x\n", hdr->data_start, hdr->data_end - hdr->data_start, pos);*/ ! result = read_exec(bprm->inode, hdr->data_start, (char *)pos, data_len, 0); if (result >= (unsigned long)-4096) { do_munmap(pos, 0); --- 288,294 ---- /*printk("Reading data from %d-%d to %x\n", hdr->data_start, hdr->data_end - hdr->data_start, pos);*/ ! result = read_exec(bprm->inode, ntohl(hdr->data_start), (char *)pos, data_len, 0); if (result >= (unsigned long)-4096) { do_munmap(pos, 0); *************** *** 310,324 **** read in the data. . */ pos = error + code_len; } #ifdef DEBUG ! printk("ROM mapping is %x, Entry point is %x, data_start is %x\n", error, hdr->entry, hdr->data_start); #endif ! current->mm->start_code = error + hdr->entry; ! current->mm->end_code = error + hdr->data_start; current->mm->start_data = pos; current->mm->end_data = pos + data_len; --- 316,331 ---- read in the data. . */ pos = error + code_len; + memset((void*)(pos + data_len), 0, bss_len + stack_len); } #ifdef DEBUG ! printk("Mapping is %x, Entry point is %x, data_start is %x\n", error, ntohl(hdr->entry), ntohl(hdr->data_start)); #endif ! current->mm->start_code = error + ntohl(hdr->entry); ! current->mm->end_code = error + ntohl(hdr->data_start); current->mm->start_data = pos; current->mm->end_data = pos + data_len; *************** *** 334,357 **** if (is_in_rom(error)) { int r; ! for(r=0;rreloc_count;r++) { ! struct flat_reloc * reloc = (struct flat_reloc*) ! (error + hdr->reloc_start + (sizeof(struct flat_reloc)*r)); ! do_reloc(reloc); } } else { int r; ! for(r=0;rreloc_count;r++) { ! struct flat_reloc reloc; unsigned long result = read_exec(bprm->inode, ! hdr->reloc_start + (sizeof(struct flat_reloc)*r), ! (char *)&reloc, sizeof(struct flat_reloc), 0); if (result >= (unsigned long)-4096) { printk("Failure reloading relocation\n"); ! } else ! do_reloc(&reloc); } } --- 341,380 ---- if (is_in_rom(error)) { int r; ! int rcnt = ntohl(hdr->reloc_count); ! ! for(r=0;rreloc_start) + (sizeof(struct flat_reloc)*r)); ! rr.lword = ntohl(rr.lword); ! do_reloc(&rr.reloc); } } else { int r; ! int rcnt = ntohl(hdr->reloc_count); ! ! for(r=0;rinode, ! ntohl(hdr->reloc_start) + (sizeof(struct flat_reloc)*r), ! (char *)&rr, sizeof(struct flat_reloc), 0); if (result >= (unsigned long)-4096) { printk("Failure reloading relocation\n"); ! } ! else ! { ! rr.lword = ntohl(rr.lword); ! do_reloc(&rr.reloc); ! } } } Index: AplioTRIO/linux/include/asm-armnommu/arch-trio/hardware.h diff -c AplioTRIO/linux/include/asm-armnommu/arch-trio/hardware.h:1.10 AplioTRIO/linux/include/asm-armnommu/arch-trio/hardware.h:1.12 *** AplioTRIO/linux/include/asm-armnommu/arch-trio/hardware.h:1.10 Mon Nov 29 10:44:59 1999 --- AplioTRIO/linux/include/asm-armnommu/arch-trio/hardware.h Wed Jan 12 17:19:13 2000 *************** *** 35,40 **** --- 35,43 ---- #define KERNTOPHYS(a) ((unsigned long)(&a)) #define GET_MEMORY_END(p) ((p->u1.s.page_size) * (p->u1.s.nr_pages)) #define PARAMS_BASE 0x1000 + + #define HARD_RESET_NOW() { arch_hard_reset(); } + //#define KERNEL_BASE (PAGE_OFFSET + 0x80000) #endif *************** *** 415,420 **** --- 418,425 ---- #define PIOB_NWDOVF (1<<6) #define PIOB_NCE1 (1<<7) #define PIOB_NCE2 (1<<8) + + #define PIO(i) (1< + + struct triokb_piomask{ + u_32 pra_mask; + u_32 prb_mask; + u_32 pca_mask; + u_32 pcb_mask; + }; + enum { + TRIOKB_PIOMASK, + }; Index: AplioTRIO/linux/include/asm-armnommu/arch-trio/trioport.h diff -c /dev/null AplioTRIO/linux/include/asm-armnommu/arch-trio/trioport.h:1.2 *** /dev/null Fri Jan 28 16:54:04 2000 --- AplioTRIO/linux/include/asm-armnommu/arch-trio/trioport.h Thu Jan 27 17:57:18 2000 *************** *** 0 **** --- 1,10 ---- + #include + + enum { + TRIOPORT_IO, + TRIOPORT_CTRL, + TRIOPORT_IRQ_ON, + TRIOPORT_IRQ_OFF, + TRIOPORT_OUT, + }; + Index: AplioTRIO/linux/include/asm-armnommu/proc-armv/processor.h diff -c AplioTRIO/linux/include/asm-armnommu/proc-armv/processor.h:1.1.1.1 AplioTRIO/linux/include/asm-armnommu/proc-armv/processor.h:1.2 *** AplioTRIO/linux/include/asm-armnommu/proc-armv/processor.h:1.1.1.1 Mon Nov 15 14:41:18 1999 --- AplioTRIO/linux/include/asm-armnommu/proc-armv/processor.h Fri Jan 28 16:19:59 2000 *************** *** 92,98 **** save->pc = (unsigned long) ret_from_sys_call; } ! #define start_thread(regs,pc,sp) \ ({ \ unsigned long *stack = (unsigned long *)sp; \ set_fs(USER_DS); \ --- 92,98 ---- save->pc = (unsigned long) ret_from_sys_call; } ! #define start_thread(regs,pc,data, sp) \ ({ \ unsigned long *stack = (unsigned long *)sp; \ set_fs(USER_DS); \ *************** *** 103,108 **** --- 103,109 ---- regs->ARM_cpsr = USR26_MODE; \ regs->ARM_pc = pc; /* pc */ \ regs->ARM_sp = sp; /* sp */ \ + regs->ARM_r10 = data; /* data segment base */ \ regs->ARM_r2 = stack[2]; /* r2 (envp) */ \ regs->ARM_r1 = stack[1]; /* r1 (argv) */ \ regs->ARM_r0 = stack[0]; /* r0 (argc) */ \ Index: AplioTRIO/linux/init/main.c diff -c AplioTRIO/linux/init/main.c:1.1.1.1 AplioTRIO/linux/init/main.c:1.3 *** AplioTRIO/linux/init/main.c:1.1.1.1 Mon Nov 15 14:41:09 1999 --- AplioTRIO/linux/init/main.c Wed Dec 29 15:32:48 1999 *************** *** 1171,1192 **** if ((open("/dev/tty1",O_RDWR,0) < 0) && (open("/dev/ttyS0",O_RDWR,0) < 0)) printk("Unable to open an initial console.\n"); ! (void) dup(0); (void) dup(0); if (!execute_command) { execve("/etc/init",argv_init,envp_init); execve("/bin/init",argv_init,envp_init); execve("/sbin/init",argv_init,envp_init); /* if this fails, fall through to original stuff */ pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD); if (pid>0) while (pid != wait(&i)) /* nothing */; } while (1) { pid = kernel_thread(do_shell, execute_command ? execute_command : "/bin/sh", --- 1171,1198 ---- if ((open("/dev/tty1",O_RDWR,0) < 0) && (open("/dev/ttyS0",O_RDWR,0) < 0)) printk("Unable to open an initial console.\n"); ! ! printk("opened console\n"); (void) dup(0); (void) dup(0); + printf("doing printf\n"); + if (!execute_command) { + printk("executing init\n"); execve("/etc/init",argv_init,envp_init); execve("/bin/init",argv_init,envp_init); execve("/sbin/init",argv_init,envp_init); /* if this fails, fall through to original stuff */ + printk("executing do_rc\n"); pid = kernel_thread(do_rc, "/etc/rc", SIGCHLD); if (pid>0) while (pid != wait(&i)) /* nothing */; } + printk("executing: %s\n", execute_command ? execute_command : "/bin/sh"); while (1) { pid = kernel_thread(do_shell, execute_command ? execute_command : "/bin/sh", *************** *** 1196,1201 **** --- 1202,1208 ---- continue; } while (1) + // printk("Waiting for child shell to die\n"); if (pid == wait(&i)) break; printf("\n\rchild %d died with code %04x\n\r",pid,i); Index: AplioTRIO/linux/kernel/ksyms.c diff -c AplioTRIO/linux/kernel/ksyms.c:1.1.1.1 AplioTRIO/linux/kernel/ksyms.c:1.2 *** AplioTRIO/linux/kernel/ksyms.c:1.1.1.1 Mon Nov 15 14:41:10 1999 --- AplioTRIO/linux/kernel/ksyms.c Wed Dec 29 15:32:51 1999 *************** *** 234,241 **** X(tty_check_change), X(tty_hung_up_p), X(do_SAK), X(console_print), ! /* filesystem registration */ X(register_filesystem), X(unregister_filesystem), --- 234,242 ---- X(tty_check_change), X(tty_hung_up_p), X(do_SAK), + #ifdef CONFIG_CONSOLE X(console_print), ! #endif /* filesystem registration */ X(register_filesystem), X(unregister_filesystem), Index: AplioTRIO/linux/lib/vsprintf.c diff -c AplioTRIO/linux/lib/vsprintf.c:1.1.1.1 AplioTRIO/linux/lib/vsprintf.c:1.2 *** AplioTRIO/linux/lib/vsprintf.c:1.1.1.1 Mon Nov 15 14:41:10 1999 --- AplioTRIO/linux/lib/vsprintf.c Mon Jan 10 16:23:16 2000 *************** *** 280,288 **** num = va_arg(args, unsigned long); else if (qualifier == 'h') if (flags & SIGN) ! num = va_arg(args, short); else ! num = va_arg(args, unsigned short); else if (flags & SIGN) num = va_arg(args, int); else --- 280,288 ---- num = va_arg(args, unsigned long); else if (qualifier == 'h') if (flags & SIGN) ! num = va_arg(args, int); else ! num = va_arg(args, unsigned); else if (flags & SIGN) num = va_arg(args, int); else