diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1999-01-03 17:49:53 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1999-01-03 17:49:53 +0000 |
commit | eb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (patch) | |
tree | 5746fea1605ff013be9b78a1556aaad7615d664a /arch/m68k | |
parent | 80ea5b1e15398277650e1197957053b5a71c08bc (diff) |
Merge with Linux 2.1.131 plus some more MIPS goodies.
Diffstat (limited to 'arch/m68k')
-rw-r--r-- | arch/m68k/amiga/amiints.c | 2 | ||||
-rw-r--r-- | arch/m68k/amiga/config.c | 22 | ||||
-rw-r--r-- | arch/m68k/atari/ataints.c | 10 | ||||
-rw-r--r-- | arch/m68k/atari/stram.c | 259 | ||||
-rw-r--r-- | arch/m68k/atari/time.c | 3 | ||||
-rw-r--r-- | arch/m68k/config.in | 13 | ||||
-rw-r--r-- | arch/m68k/kernel/entry.S | 2 | ||||
-rw-r--r-- | arch/m68k/kernel/m68k_defs.h | 6 | ||||
-rw-r--r-- | arch/m68k/kernel/m68k_ksyms.c | 5 | ||||
-rw-r--r-- | arch/m68k/kernel/ptrace.c | 8 | ||||
-rw-r--r-- | arch/m68k/kernel/traps.c | 2 | ||||
-rw-r--r-- | arch/m68k/mac/adb-bus.c | 5 | ||||
-rw-r--r-- | arch/m68k/mac/config.c | 86 | ||||
-rw-r--r-- | arch/m68k/mac/debug.c | 103 | ||||
-rw-r--r-- | arch/m68k/mac/macboing.c | 40 | ||||
-rw-r--r-- | arch/m68k/mac/macints.c | 87 | ||||
-rw-r--r-- | arch/m68k/mac/mackeyb.c | 16 | ||||
-rw-r--r-- | arch/m68k/mac/psc.h | 18 | ||||
-rw-r--r-- | arch/m68k/mac/via6522.c | 188 | ||||
-rw-r--r-- | arch/m68k/mac/via6522.h | 24 | ||||
-rw-r--r-- | arch/m68k/mm/memory.c | 17 |
21 files changed, 552 insertions, 364 deletions
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c index 9aa47cf7c..25955213e 100644 --- a/arch/m68k/amiga/amiints.c +++ b/arch/m68k/amiga/amiints.c @@ -288,12 +288,14 @@ void amiga_enable_irq(unsigned int irq) } if (irq >= IRQ_AMIGA_CIAB) { + cia_set_irq(&ciab_base, (1 << (irq - IRQ_AMIGA_CIAB))); cia_able_irq(&ciab_base, CIA_ICR_SETCLR | (1 << (irq - IRQ_AMIGA_CIAB))); return; } if (irq >= IRQ_AMIGA_CIAA) { + cia_set_irq(&ciaa_base, (1 << (irq - IRQ_AMIGA_CIAA))); cia_able_irq(&ciaa_base, CIA_ICR_SETCLR | (1 << (irq - IRQ_AMIGA_CIAA))); return; diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c index 9483c97b3..63cb5265c 100644 --- a/arch/m68k/amiga/config.c +++ b/arch/m68k/amiga/config.c @@ -398,6 +398,28 @@ __initfunc(void config_amiga(void)) /* ensure that the DMA master bit is set */ custom.dmacon = DMAF_SETCLR | DMAF_MASTER; + /* don't use Z2 RAM as system memory on Z3 capable machines */ + if (AMIGAHW_PRESENT(ZORRO3)) { + int i, j; + u32 disabled_z2mem = 0; + for (i = 0; i < m68k_num_memory; i++) + if (m68k_memory[i].addr < 16*1024*1024) { + if (i == 0) { + /* don't cut off the branch we're sitting on */ + printk("Warning: kernel runs in Zorro II memory\n"); + continue; + } + disabled_z2mem += m68k_memory[i].size; + m68k_num_memory--; + for (j = i; j < m68k_num_memory; j++) + m68k_memory[j] = m68k_memory[j+1]; + i--; + } + if (disabled_z2mem) + printk("%dK of Zorro II memory will not be used as system memory\n", + disabled_z2mem>>10); + } + /* initialize chipram allocator */ amiga_chip_init (); diff --git a/arch/m68k/atari/ataints.c b/arch/m68k/atari/ataints.c index 15e4c2d09..0f6ddf111 100644 --- a/arch/m68k/atari/ataints.c +++ b/arch/m68k/atari/ataints.c @@ -419,6 +419,7 @@ int atari_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_r unsigned long flags, const char *devname, void *dev_id) { int vector; + unsigned long oflags = flags; /* * The following is a hack to make some PCI card drivers work, @@ -427,9 +428,14 @@ int atari_request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_r flags &= ~SA_SHIRQ; + if (flags == SA_INTERRUPT) { + printk ("%s: SA_INTERRUPT changed to IRQ_TYPE_SLOW for %s\n", + __FUNCTION__, devname); + flags = IRQ_TYPE_SLOW; + } if (flags < IRQ_TYPE_SLOW || flags > IRQ_TYPE_PRIO) { - printk ("%s: Bad irq type %ld requested from %s\n", - __FUNCTION__, flags, devname); + printk ("%s: Bad irq type 0x%lx <0x%lx> requested from %s\n", + __FUNCTION__, flags, oflags, devname); return -EINVAL; } if (!IS_VALID_INTNO(irq)) { diff --git a/arch/m68k/atari/stram.c b/arch/m68k/atari/stram.c index b3741ed96..cade2173a 100644 --- a/arch/m68k/atari/stram.c +++ b/arch/m68k/atari/stram.c @@ -19,6 +19,8 @@ #include <linux/malloc.h> #include <linux/vmalloc.h> #include <linux/pagemap.h> +#include <linux/shm.h> + #include <asm/setup.h> #include <asm/machdep.h> #include <asm/page.h> @@ -26,6 +28,7 @@ #include <asm/atarihw.h> #include <asm/atari_stram.h> #include <asm/io.h> +#include <asm/semaphore.h> #ifdef CONFIG_STRAM_SWAP @@ -116,6 +119,10 @@ * since the freeing algorithms are also blind to DMA capability of pages. */ +/* 1998-10-20: ++andreas + unswap_by_move disabled because it does not handle swapped shm pages. +*/ + #ifdef CONFIG_STRAM_SWAP #define ALIGN_IF_SWAP(x) PAGE_ALIGN(x) #else @@ -192,6 +199,9 @@ static struct swap_info_struct *stram_swap_info; /* The ST-RAM's swap type */ static int stram_swap_type; +/* Semaphore for get_stram_region. */ +static struct semaphore stram_swap_sem = MUTEX; + /* major and minor device number of the ST-RAM device; for the major, we use * the same as Amiga z2ram, which is really similar and impossible on Atari, * and for the minor a relatively odd number to avoid the user creating and @@ -215,25 +225,6 @@ static unsigned stat_swap_force = 0; #ifdef CONFIG_STRAM_SWAP static int swap_init( unsigned long start_mem, unsigned long swap_data ); -static inline int unswap_pte( struct vm_area_struct * vma, unsigned long - address, pte_t *dir, unsigned long entry, - unsigned long page, int isswap ); -static inline int unswap_pmd( struct vm_area_struct * vma, pmd_t *dir, - unsigned long address, unsigned long size, - unsigned long offset, unsigned long entry, - unsigned long page, int isswap ); -static inline int unswap_pgd( struct vm_area_struct * vma, pgd_t *dir, - unsigned long address, unsigned long size, - unsigned long entry, unsigned long page, int - isswap ); -static int unswap_vma( struct vm_area_struct * vma, pgd_t *pgdir, unsigned - long entry, unsigned long page, int isswap ); -static int unswap_process( struct mm_struct * mm, unsigned long entry, - unsigned long page, int isswap ); -static int unswap_by_move(unsigned short *, unsigned long, unsigned long, - unsigned long); -static int unswap_by_read(unsigned short *, unsigned long, unsigned long, - unsigned long); static void *get_stram_region( unsigned long n_pages ); static void free_stram_region( unsigned long offset, unsigned long n_pages ); @@ -263,7 +254,7 @@ static int remove_region( BLOCK *block ); * This init function is called very early by atari/config.c * It initializes some internal variables needed for stram_alloc() */ -__initfunc(void atari_stram_init( void )) +void __init atari_stram_init(void) { int i; @@ -273,7 +264,7 @@ __initfunc(void atari_stram_init( void )) /* determine whether kernel code resides in ST-RAM (then ST-RAM is the * first memory block at virtual 0x0) */ - stram_start = phys_to_virt( 0 ); + stram_start = (unsigned long)phys_to_virt(0); kernel_in_stram = (stram_start == 0); for( i = 0; i < m68k_num_memory; ++i ) { @@ -294,7 +285,7 @@ __initfunc(void atari_stram_init( void )) * This function is called from mem_init() to reserve the pages needed for * ST-RAM management. */ -__initfunc(void atari_stram_reserve_pages( unsigned long start_mem )) +void __init atari_stram_reserve_pages(unsigned long start_mem) { #ifdef CONFIG_STRAM_SWAP /* if max_swap_size is negative (i.e. no stram_swap= option given), @@ -573,8 +564,7 @@ void atari_stram_free( void *addr ) * Initialize ST-RAM swap device * (lots copied and modified from sys_swapon() in mm/swapfile.c) */ -__initfunc(static int swap_init( unsigned long start_mem, - unsigned long swap_data )) +static int __init swap_init(unsigned long start_mem, unsigned long swap_data) { static struct dentry fake_dentry[3]; struct swap_info_struct *p; @@ -691,75 +681,64 @@ __initfunc(static int swap_init( unsigned long start_mem, /* * The swap entry has been read in advance, and we return 1 to indicate * that the page has been used or is no longer needed. + * + * Always set the resulting pte to be nowrite (the same as COW pages + * after one process has exited). We don't know just how many PTEs will + * share this swap entry, so be cautious and let do_wp_page work out + * what to do if a write is requested later. */ -static inline int unswap_pte( struct vm_area_struct * vma, unsigned long - address, pte_t *dir, unsigned long entry, - unsigned long page, int isswap ) +static inline void unswap_pte(struct vm_area_struct * vma, unsigned long + address, pte_t *dir, unsigned long entry, + unsigned long page /*, int isswap */) { pte_t pte = *dir; if (pte_none(pte)) - return 0; + return; if (pte_present(pte)) { - struct page *pg; - unsigned long page_nr = MAP_NR(pte_page(pte)); - unsigned long pg_swap_entry; - - if (page_nr >= max_mapnr) - return 0; - pg = mem_map + page_nr; - if (!(pg_swap_entry = in_swap_cache(pg))) - return 0; - if (pg_swap_entry != entry) - return 0; - if (isswap) { - DPRINTK( "unswap_pte: page %08lx = entry %08lx was in swap cache; " - "exchanging to %08lx\n", - page_address(pg), entry, page ); - pg->offset = page; - swap_free(entry); - return 1; - } - else { - DPRINTK( "unswap_pte: page %08lx = entry %08lx was in swap cache; " - "deleted there\n", page_address(pg), entry ); - delete_from_swap_cache(pg); + /* If this entry is swap-cached, then page must already + hold the right address for any copies in physical + memory */ + if (pte_page(pte) != page) + return; + if (0 /* isswap */) + mem_map[MAP_NR(pte_page(pte))].offset = page; + else + /* We will be removing the swap cache in a moment, so... */ set_pte(dir, pte_mkdirty(pte)); - free_page(page); - return 1; - } + return; } if (pte_val(pte) != entry) - return 0; + return; - if (isswap) { + if (0 /* isswap */) { DPRINTK( "unswap_pte: replacing entry %08lx by %08lx", entry, page ); set_pte(dir, __pte(page)); } else { DPRINTK( "unswap_pte: replacing entry %08lx by new page %08lx", entry, page ); - set_pte(dir, pte_mkwrite(pte_mkdirty(mk_pte(page,vma->vm_page_prot)))); + set_pte(dir, pte_mkdirty(mk_pte(page,vma->vm_page_prot))); + atomic_inc(&mem_map[MAP_NR(page)].count); ++vma->vm_mm->rss; } swap_free(entry); - return 1; } -static inline int unswap_pmd( struct vm_area_struct * vma, pmd_t *dir, - unsigned long address, unsigned long size, - unsigned long offset, unsigned long entry, - unsigned long page, int isswap ) +static inline void unswap_pmd(struct vm_area_struct * vma, pmd_t *dir, + unsigned long address, unsigned long size, + unsigned long offset, unsigned long entry, + unsigned long page /* , int isswap */) { pte_t * pte; unsigned long end; if (pmd_none(*dir)) - return 0; + return; if (pmd_bad(*dir)) { printk("unswap_pmd: bad pmd (%08lx)\n", pmd_val(*dir)); pmd_clear(dir); - return 0; + return; } pte = pte_offset(dir, address); offset += address & PMD_MASK; @@ -768,29 +747,27 @@ static inline int unswap_pmd( struct vm_area_struct * vma, pmd_t *dir, if (end > PMD_SIZE) end = PMD_SIZE; do { - if (unswap_pte( vma, offset+address-vma->vm_start, pte, entry, - page, isswap )) - return 1; + unswap_pte(vma, offset+address-vma->vm_start, pte, entry, + page /* , isswap */); address += PAGE_SIZE; pte++; } while (address < end); - return 0; } -static inline int unswap_pgd( struct vm_area_struct * vma, pgd_t *dir, - unsigned long address, unsigned long size, - unsigned long entry, unsigned long page, - int isswap ) +static inline void unswap_pgd(struct vm_area_struct * vma, pgd_t *dir, + unsigned long address, unsigned long size, + unsigned long entry, unsigned long page + /* , int isswap */) { pmd_t * pmd; unsigned long offset, end; if (pgd_none(*dir)) - return 0; + return; if (pgd_bad(*dir)) { printk("unswap_pgd: bad pgd (%08lx)\n", pgd_val(*dir)); pgd_clear(dir); - return 0; + return; } pmd = pmd_offset(dir, address); offset = address & PGDIR_MASK; @@ -799,53 +776,45 @@ static inline int unswap_pgd( struct vm_area_struct * vma, pgd_t *dir, if (end > PGDIR_SIZE) end = PGDIR_SIZE; do { - if (unswap_pmd( vma, pmd, address, end - address, offset, entry, - page, isswap )) - return 1; + unswap_pmd(vma, pmd, address, end - address, offset, entry, + page /* , isswap */); address = (address + PMD_SIZE) & PMD_MASK; pmd++; } while (address < end); - return 0; } -static int unswap_vma( struct vm_area_struct * vma, pgd_t *pgdir, - unsigned long entry, unsigned long page, int isswap ) +static void unswap_vma(struct vm_area_struct * vma, pgd_t *pgdir, + unsigned long entry, unsigned long page + /* , int isswap */) { unsigned long start = vma->vm_start, end = vma->vm_end; - while( start < end ) { - if (unswap_pgd( vma, pgdir, start, end - start, entry, page, isswap )) - return 1; + while (start < end) { + unswap_pgd(vma, pgdir, start, end - start, entry, page + /* , isswap */); start = (start + PGDIR_SIZE) & PGDIR_MASK; pgdir++; } - return 0; } -static int unswap_process( struct mm_struct * mm, unsigned long entry, - unsigned long page, int isswap ) +static void unswap_process(struct mm_struct * mm, unsigned long entry, + unsigned long page /* , int isswap */) { struct vm_area_struct* vma; - int retval = 0; /* * Go through process' page directory. */ if (!mm || mm == &init_mm) - return 0; - down(&mm->mmap_sem); - for( vma = mm->mmap; vma; vma = vma->vm_next ) { + return; + for (vma = mm->mmap; vma; vma = vma->vm_next) { pgd_t * pgd = pgd_offset(mm, vma->vm_start); - if (unswap_vma( vma, pgd, entry, page, isswap )) { - retval = 1; - break; - } + unswap_vma(vma, pgd, entry, page /* , isswap */); } - up(&mm->mmap_sem); - return retval; } +#if 0 static int unswap_by_move(unsigned short *map, unsigned long max, unsigned long start, unsigned long n_pages) { @@ -899,14 +868,17 @@ static int unswap_by_move(unsigned short *map, unsigned long max, #endif while( map[i] ) { + read_lock(&tasklist_lock); for_each_task(p) { if (unswap_process( p->mm, SWP_ENTRY( stram_swap_type, i ), entry, 1 )) { + read_unlock(&tasklist_lock); map[j]++; goto repeat; } } - if (map[i] && map[i] != 127) { + read_unlock(&tasklist_lock); + if (map[i] && map[i] != SWAP_MAP_MAX) { printk( KERN_ERR "get_stram_region: ST-RAM swap page %lu " "not used by any process\n", i ); /* quit while loop and overwrite bad map entry */ @@ -932,13 +904,15 @@ static int unswap_by_move(unsigned short *map, unsigned long max, } return( 0 ); } +#endif static int unswap_by_read(unsigned short *map, unsigned long max, unsigned long start, unsigned long n_pages) { struct task_struct *p; - unsigned long entry, page = 0; + unsigned long entry, page; unsigned long i; + struct page *page_map; DPRINTK( "unswapping %lu..%lu by reading in\n", start, start+n_pages-1 ); @@ -949,43 +923,35 @@ static int unswap_by_read(unsigned short *map, unsigned long max, "reserved??\n", i ); continue; } - entry = SWP_ENTRY( stram_swap_type, i ); - DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n", - i, map[i], nr_swap_pages ); - while( map[i] ) { - if (!page && !(page = __get_free_page(GFP_KERNEL))) { - printk( KERN_NOTICE "get_stram_region: out of memory\n" ); - return( -ENOMEM ); - } - DPRINTK( "unswap: reading swap page %lu to %08lx\n", i, page ); - rw_swap_page( READ, entry, (char *)page, 1 ); - - for_each_task(p) { - if (unswap_process( p->mm, entry, page, 0 )) { - page = 0; -#ifdef DO_PROC - stat_swap_force++; -#endif - break; - } - } - if (page) { - /* - * If we couldn't find an entry, there are several - * possible reasons: someone else freed it first, - * we freed the last reference to an overflowed entry, - * or the system has lost track of the use counts. - */ - if (map[i] && map[i] != SWAP_MAP_MAX) - printk( KERN_ERR "get_stram_region: swap entry %08lx " - "not used by any process\n", entry ); - /* quit while loop and overwrite bad map entry */ - if (!map[i]) { - DPRINTK( "unswap: map[i] became 0\n" ); - } - break; + if (map[i]) { + entry = SWP_ENTRY(stram_swap_type, i); + DPRINTK("unswap: map[i=%lu]=%u nr_swap=%u\n", + i, map[i], nr_swap_pages); + + /* Get a page for the entry, using the existing + swap cache page if there is one. Otherwise, + get a clean page and read the swap into it. */ + page_map = read_swap_cache(entry); + if (page_map) { + page = page_address(page_map); + read_lock(&tasklist_lock); + for_each_task(p) + unswap_process(p->mm, entry, page + /* , 0 */); + read_unlock(&tasklist_lock); + shm_unuse(entry, page); + /* Now get rid of the extra reference to + the temporary page we've been using. */ + if (PageSwapCache(page_map)) + delete_from_swap_cache(page_map); + __free_page(page_map); + #ifdef DO_PROC + stat_swap_force++; + #endif } + else if (map[i]) + return -ENOMEM; } DPRINTK( "unswap: map[i=%lu]=%u nr_swap=%u\n", @@ -998,9 +964,7 @@ static int unswap_by_read(unsigned short *map, unsigned long max, --nr_swap_pages; } - if (page) - free_page(page); - return( 0 ); + return 0; } /* @@ -1015,7 +979,9 @@ static void *get_stram_region( unsigned long n_pages ) void *ret = NULL; DPRINTK( "get_stram_region(n_pages=%lu)\n", n_pages ); - + + down(&stram_swap_sem); + /* disallow writing to the swap device now */ stram_swap_info->flags = SWP_USED; @@ -1026,9 +992,14 @@ static void *get_stram_region( unsigned long n_pages ) DPRINTK( "get_stram_region: region starts at %lu, has %lu free pages\n", start, region_free ); +#if 0 err = ((total_free-region_free >= n_pages-region_free) ? unswap_by_move( map, max, start, n_pages ) : unswap_by_read( map, max, start, n_pages )); +#else + err = unswap_by_read(map, max, start, n_pages); +#endif + if (err) goto end; @@ -1036,6 +1007,7 @@ static void *get_stram_region( unsigned long n_pages ) end: /* allow using swap device again */ stram_swap_info->flags = SWP_WRITEOK; + up(&stram_swap_sem); DPRINTK( "get_stram_region: returning %p\n", ret ); return( ret ); } @@ -1110,7 +1082,7 @@ static unsigned long find_free_region(unsigned long n_pages, start_over: /* increment tail until final window size reached, and count free pages */ nfree = 0; - for( tail = head; tail-head < n_pages && tail < max-n_pages; ++tail ) { + for( tail = head; tail-head < n_pages && tail < max; ++tail ) { if (map[tail] == SWAP_MAP_BAD) { head = tail+1; goto start_over; @@ -1165,7 +1137,7 @@ static unsigned long find_free_region(unsigned long n_pages, /* setup parameters from command line */ -__initfunc(void stram_swap_setup(char *str, int *ints)) +void __init stram_swap_setup(char *str, int *ints) { if (ints[0] >= 1) max_swap_size = ((ints[1] < 0 ? 0 : ints[1]) * 1024) & PAGE_MASK; @@ -1262,7 +1234,7 @@ static struct file_operations stram_fops = { block_fsync /* fsync */ }; -__initfunc(int stram_device_init(void)) +int __init stram_device_init(void) { if (!MACH_IS_ATARI) @@ -1465,9 +1437,10 @@ int get_stram_list( char *buf ) for( p = alloc_list; p; p = p->next ) { if (len + 50 >= PAGE_SIZE) break; - PRINT_PROC( "0x%08lx-0x%08lx: %s (", - virt_to_phys(p->start), - virt_to_phys(p->start+p->size-1), p->owner ); + PRINT_PROC("0x%08lx-0x%08lx: %s (", + virt_to_phys((void *)p->start), + virt_to_phys((void *)p->start+p->size-1), + p->owner); if (p->flags & BLOCK_STATIC) PRINT_PROC( "static)\n" ); else if (p->flags & BLOCK_GFP) diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c index 79c4f48f2..0fd3795a5 100644 --- a/arch/m68k/atari/time.c +++ b/arch/m68k/atari/time.c @@ -279,8 +279,7 @@ int atari_tt_hwclk( int op, struct hwclk_time *t ) while( RTC_READ(RTC_FREQ_SELECT) & RTC_UIP ) { current->state = TASK_INTERRUPTIBLE; - current->timeout = jiffies + HWCLK_POLL_INTERVAL; - schedule(); + schedule_timeout(HWCLK_POLL_INTERVAL); } save_flags(flags); diff --git a/arch/m68k/config.in b/arch/m68k/config.in index 21ac9badc..8fe84aecd 100644 --- a/arch/m68k/config.in +++ b/arch/m68k/config.in @@ -32,6 +32,7 @@ fi bool 'Macintosh support' CONFIG_MAC if [ "$CONFIG_MAC" = "y" ]; then define_bool CONFIG_NUBUS y + define_bool CONFIG_M68K_L2_CACHE y fi bool 'Apollo support' CONFIG_APOLLO bool 'VME (Motorola and BVM) support' CONFIG_VME @@ -155,6 +156,7 @@ if [ "$CONFIG_ZORRO" = "y" ]; then if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then bool 'A4091 SCSI support' CONFIG_A4091_SCSI bool 'WarpEngine SCSI support' CONFIG_WARPENGINE_SCSI + bool 'Blizzard PowerUP 603e+ SCSI' CONFIG_BLZ603EPLUS_SCSI bool 'Cyberstorm Mk III SCSI support' CONFIG_CYBERSTORMIII_SCSI # bool 'GVP Turbo 040/060 SCSI support' CONFIG_GVP_TURBO_SCSI fi @@ -171,6 +173,7 @@ if [ "$CONFIG_ATARI" = "y" ]; then fi if [ "$CONFIG_MAC" = "y" ]; then bool 'MAC NCR5380 SCSI' CONFIG_MAC_SCSI + bool 'MAC NCR53c9[46] SCSI' CONFIG_SCSI_MAC_ESP fi #dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI @@ -211,6 +214,7 @@ fi tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER if [ "$CONFIG_ZORRO" = "y" ]; then tristate 'Ariadne support' CONFIG_ARIADNE + tristate 'Ariadne II support' CONFIG_ARIADNE2 tristate 'A2065 support' CONFIG_A2065 tristate 'Hydra support' CONFIG_HYDRA fi @@ -222,6 +226,8 @@ if [ "$CONFIG_APOLLO" = "y" ] ; then fi if [ "$CONFIG_MAC" = "y" ]; then bool 'Mac NS 8390 based ethernet cards' CONFIG_DAYNAPORT + bool 'AV Macintosh onboard MACE ethernet' CONFIG_MACMACE + bool 'Macintosh onboard SONIC ethernet' CONFIG_MACSONIC fi if [ "$CONFIG_VME" = "y" -a "$CONFIG_MVME16x" = "y" ]; then bool 'MVME16x Ethernet support' CONFIG_MVME16x_NET @@ -260,7 +266,7 @@ fi tristate 'Parallel printer support' CONFIG_M68K_PRINTER if [ "$CONFIG_ZORRO" = "y" ]; then - dep_tristate 'Multiface Card III parallel support' CONFIG_MULTIFACE_III_LP $CONFIG_PRINTER + dep_tristate 'Multiface Card III parallel support' CONFIG_MULTIFACE_III_LP $CONFIG_M68K_PRINTER fi if [ "$CONFIG_AMIGA" = "y" ]; then tristate 'Amiga mouse support' CONFIG_AMIGAMOUSE @@ -328,11 +334,6 @@ if [ "$CONFIG_WATCHDOG" != "n" ]; then bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT bool ' Software Watchdog' CONFIG_SOFT_WATCHDOG fi -if [ "$CONFIG_VME" = "y" ]; then - define_bool CONFIG_UMISC y -else - bool 'Support for user misc device modules' CONFIG_UMISC -fi if [ "$CONFIG_ATARI" = "y" ]; then bool 'Enhanced Real Time Clock Support' CONFIG_RTC fi diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S index f4c1343ca..b3e15387c 100644 --- a/arch/m68k/kernel/entry.S +++ b/arch/m68k/kernel/entry.S @@ -396,7 +396,7 @@ SYMBOL_NAME_LABEL(resume) .data ALIGN SYMBOL_NAME_LABEL(sys_call_table) - .long SYMBOL_NAME(sys_setup) /* 0 */ + .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/ .long SYMBOL_NAME(sys_exit) .long SYMBOL_NAME(sys_fork) .long SYMBOL_NAME(sys_read) diff --git a/arch/m68k/kernel/m68k_defs.h b/arch/m68k/kernel/m68k_defs.h index b32e6a1c9..992d390c7 100644 --- a/arch/m68k/kernel/m68k_defs.h +++ b/arch/m68k/kernel/m68k_defs.h @@ -3,6 +3,6 @@ */ #define TS_MAGICKEY 0x5a5a5a5a -#define TS_TSS 482 -#define TS_ESP0 502 -#define TS_FPU 506 +#define TS_TSS 478 +#define TS_ESP0 498 +#define TS_FPU 502 diff --git a/arch/m68k/kernel/m68k_ksyms.c b/arch/m68k/kernel/m68k_ksyms.c index ee73b3ff2..40b692e0c 100644 --- a/arch/m68k/kernel/m68k_ksyms.c +++ b/arch/m68k/kernel/m68k_ksyms.c @@ -7,6 +7,7 @@ #include <linux/elfcore.h> #include <linux/in6.h> #include <linux/interrupt.h> +#include <linux/config.h> #include <asm/setup.h> #include <asm/machdep.h> @@ -30,9 +31,13 @@ EXPORT_SYMBOL(m68k_cputype); EXPORT_SYMBOL(m68k_is040or060); EXPORT_SYMBOL(cache_push); EXPORT_SYMBOL(cache_clear); +#ifndef CONFIG_SINGLE_MEMORY_CHUNK EXPORT_SYMBOL(mm_vtop); EXPORT_SYMBOL(mm_ptov); EXPORT_SYMBOL(mm_end_of_chunk); +#endif +EXPORT_SYMBOL(mm_vtop_fallback); +EXPORT_SYMBOL(m68k_memory); EXPORT_SYMBOL(kernel_map); EXPORT_SYMBOL(m68k_debug_device); EXPORT_SYMBOL(dump_fpu); diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c index da91d32de..9888d83c1 100644 --- a/arch/m68k/kernel/ptrace.c +++ b/arch/m68k/kernel/ptrace.c @@ -450,10 +450,10 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) else child->flags &= ~PF_TRACESYS; child->exit_code = data; - wake_up_process(child); /* make sure the single step bit is not set. */ tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); put_reg(child, PT_SR, tmp); + wake_up_process(child); ret = 0; goto out; } @@ -469,11 +469,11 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) ret = 0; if (child->state == TASK_ZOMBIE) /* already dead */ goto out; - wake_up_process(child); child->exit_code = SIGKILL; /* make sure the single step bit is not set. */ tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); put_reg(child, PT_SR, tmp); + wake_up_process(child); goto out; } @@ -487,9 +487,9 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) tmp = get_reg(child, PT_SR) | (TRACE_BITS << 16); put_reg(child, PT_SR, tmp); - wake_up_process(child); child->exit_code = data; /* give it a chance to run. */ + wake_up_process(child); ret = 0; goto out; } @@ -502,7 +502,6 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) if ((unsigned long) data > _NSIG) goto out; child->flags &= ~(PF_PTRACED|PF_TRACESYS); - wake_up_process(child); child->exit_code = data; write_lock_irqsave(&tasklist_lock, flags); REMOVE_LINKS(child); @@ -512,6 +511,7 @@ asmlinkage int sys_ptrace(long request, long pid, long addr, long data) /* make sure the single step bit is not set. */ tmp = get_reg(child, PT_SR) & ~(TRACE_BITS << 16); put_reg(child, PT_SR, tmp); + wake_up_process(child); ret = 0; goto out; } diff --git a/arch/m68k/kernel/traps.c b/arch/m68k/kernel/traps.c index ff73709b7..1f07014b2 100644 --- a/arch/m68k/kernel/traps.c +++ b/arch/m68k/kernel/traps.c @@ -452,7 +452,7 @@ static inline void bus_error030 (struct frame *fp) #endif errorcode = (mmusr & MMU_I) ? 0 : 1; - if (!(ssw & RW) || ssw & RM) + if (!(ssw & RW) || (ssw & RM)) errorcode |= 2; if (mmusr & (MMU_I | MMU_WP)) { diff --git a/arch/m68k/mac/adb-bus.c b/arch/m68k/mac/adb-bus.c index 642164314..b466ce533 100644 --- a/arch/m68k/mac/adb-bus.c +++ b/arch/m68k/mac/adb-bus.c @@ -245,13 +245,16 @@ void adb_bus_init(void) via_write(via1, vIFR, SR_INT); /* get those pesky clock ticks we missed while booting */ - for ( i = 0; i < 30; i++) { + for ( i = 0; i < 60; i++) { udelay(ADB_DELAY); adb_hw_setup_IIsi(); udelay(ADB_DELAY); if (via_read(via1, vBufB) & TREQ) break; } + if (i == 60) + printk("adb_IIsi: maybe bus jammed ??\n"); + /* * Ok we probably ;) have a ready to use adb bus. Its also */ diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c index fe77ded05..f410182e0 100644 --- a/arch/m68k/mac/config.c +++ b/arch/m68k/mac/config.c @@ -83,9 +83,9 @@ extern int mac_get_irq_list (char *); /* Mac specific timer functions */ extern unsigned long mac_gettimeoffset (void); -extern void mac_gettod (int *, int *, int *, int *, int *, int *); -extern int mac_hwclk (int, struct hwclk_time *); -extern int mac_set_clock_mmss (unsigned long); +static void mac_gettod (int *, int *, int *, int *, int *, int *); +static int mac_hwclk (int, struct hwclk_time *); +static int mac_set_clock_mmss (unsigned long); extern void via_init_clock(void (*func)(int, void *, struct pt_regs *)); extern void (*kd_mksound)(unsigned int, unsigned int); @@ -123,7 +123,7 @@ void mac_bang(int irq, void *vector, struct pt_regs *p) mac_reset(); } -void mac_sched_init(void (*vector)(int, void *, struct pt_regs *)) +static void mac_sched_init(void (*vector)(int, void *, struct pt_regs *)) { via_init_clock(vector); } @@ -135,7 +135,7 @@ extern int console_loglevel; * the system time. */ -void mac_gettod (int *yearp, int *monp, int *dayp, +static void mac_gettod (int *yearp, int *monp, int *dayp, int *hourp, int *minp, int *secp) { unsigned long time; @@ -192,7 +192,7 @@ void mac_gettod (int *yearp, int *monp, int *dayp, * TBI: read and write hwclock */ -int mac_hwclk( int op, struct hwclk_time *t ) +static int mac_hwclk( int op, struct hwclk_time *t ) { return 0; } @@ -201,7 +201,7 @@ int mac_hwclk( int op, struct hwclk_time *t ) * TBI: set minutes/seconds in hwclock */ -int mac_set_clock_mmss (unsigned long nowtime) +static int mac_set_clock_mmss (unsigned long nowtime) { short real_seconds = nowtime % 60, real_minutes = (nowtime / 60) % 60; @@ -280,10 +280,26 @@ __initfunc(int mac_parse_bootinfo(const struct bi_record *record)) return(unknown); } +/* + * Flip into 24bit mode for an instant - flushes the L2 cache card. We + * have to disable interrupts for this. Our IRQ handlers will crap + * themselves if they take an IRQ in 24bit mode! + */ + +static void mac_cache_card_flush(int writeback) +{ + unsigned long flags; + save_flags(flags); + cli(); + via_write(via2, vBufB, via_read(via2,vBufB)&~VIA2B_vMode32); + via_write(via2, vBufB, via_read(via2,vBufB)|VIA2B_vMode32); + restore_flags(flags); +} + __initfunc(void config_mac(void)) { - if (MACH_IS_ATARI || MACH_IS_AMIGA) { + if (!MACH_IS_MAC) { printk("ERROR: no Mac, but config_mac() called!! \n"); } @@ -338,7 +354,17 @@ __initfunc(void config_mac(void)) mac_identify(); mac_report_hardware(); - + + if( + /* Cache cards */ + macintosh_config->ident == MAC_MODEL_IICI|| + macintosh_config->ident == MAC_MODEL_IISI|| + macintosh_config->ident == MAC_MODEL_IICX|| + /* On board L2 cache */ + macintosh_config->ident == MAC_MODEL_IIFX) + { + mach_l2_flush = mac_cache_card_flush; + } /* goes on forever if timers broken */ #ifdef MAC_DEBUG_SOUND mac_mksound(1000,10); @@ -349,7 +375,6 @@ __initfunc(void config_mac(void)) */ nubus_sweep_video(); - } @@ -411,23 +436,23 @@ static struct mac_model mac_data_table[]= { MAC_MODEL_LCIII,"LC III", MAC_ADB_IISI, MAC_VIA_IIci, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, /* - * Quadra (only 68030 ones will actually work!). Not much odd. Video is at - * 0xF9000000, via is like a MacII. We label it differently as some of the - * stuff connected to VIA2 seems different. Better SCSI chip and ???? onboard ethernet - * in all cases using a NatSemi SONIC. The 700, 900 and 950 have some I/O chips in the wrong - * place to confuse us. The 840AV seems to have a scsi location of its own + * Quadra. Video is at 0xF9000000, via is like a MacII. We label it differently + * as some of the stuff connected to VIA2 seems different. Better SCSI chip and + * onboard ethernet using a NatSemi SONIC except the 660AV and 840AV which use an + * AMD 79C940 (MACE). + * The 700, 900 and 950 have some I/O chips in the wrong place to + * confuse us. The 840AV has a SCSI location of its own (same as + * the 660AV). */ - - { MAC_MODEL_Q605, "Quadra 605", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_SONIC, MAC_NUBUS}, + + { MAC_MODEL_Q605, "Quadra 605", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_Q610, "Quadra 610", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_SONIC, MAC_NUBUS}, { MAC_MODEL_Q630, "Quadra 630", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_QUADRA, MAC_SCC_QUADRA, MAC_ETHER_SONIC, MAC_NUBUS}, { MAC_MODEL_Q650, "Quadra 650", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_SONIC, MAC_NUBUS}, /* The Q700 does have a NS Sonic */ - { MAC_MODEL_Q700, "Quadra 700", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA2, MAC_IDE_NONE, MAC_SCC_QUADRA2, MAC_ETHER_SONIC, MAC_NUBUS}, + { MAC_MODEL_Q700, "Quadra 700", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA2, MAC_IDE_NONE, MAC_SCC_QUADRA2, MAC_ETHER_SONIC, MAC_NUBUS}, { MAC_MODEL_Q800, "Quadra 800", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_SONIC, MAC_NUBUS}, - /* Does the 840AV have ethernet ??? documents seem to indicate its not quite a - Quadra in this respect ? */ - { MAC_MODEL_Q840, "Quadra 840AV", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA3, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_Q840, "Quadra 840AV", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA3, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_MACE, MAC_NUBUS}, /* These might have IOP problems */ { MAC_MODEL_Q900, "Quadra 900", MAC_ADB_IISI, MAC_VIA_QUADRA, MAC_SCSI_QUADRA2, MAC_IDE_NONE, MAC_SCC_IOP, MAC_ETHER_SONIC, MAC_NUBUS}, { MAC_MODEL_Q950, "Quadra 950", MAC_ADB_IISI, MAC_VIA_QUADRA, MAC_SCSI_QUADRA2, MAC_IDE_NONE, MAC_SCC_IOP, MAC_ETHER_SONIC, MAC_NUBUS}, @@ -440,7 +465,7 @@ static struct mac_model mac_data_table[]= { MAC_MODEL_P475, "Performa 475", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_P475F, "Performa 475", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_P520, "Performa 520", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, - { MAC_MODEL_P550, "Performa 550", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_P550, "Performa 550", MAC_ADB_CUDA, MAC_VIA_IIci, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_P575, "Performa 575", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_P588, "Performa 588", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_TV, "TV", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_II, MAC_ETHER_NONE, MAC_NUBUS}, @@ -452,8 +477,8 @@ static struct mac_model mac_data_table[]= * Centris - just guessing again; maybe like Quadra */ - { MAC_MODEL_C610, "Centris 610", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, - { MAC_MODEL_C650, "Centris 650", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_C610, "Centris 610", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_C650, "Centris 650", MAC_ADB_II, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_C660, "Centris 660AV", MAC_ADB_CUDA, MAC_VIA_QUADRA, MAC_SCSI_QUADRA3, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, /* @@ -467,10 +492,10 @@ static struct mac_model mac_data_table[]= { MAC_MODEL_PB160, "PowerBook 160", MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_PB165, "PowerBook 165", MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_PB165C, "PowerBook 165c", MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, - { MAC_MODEL_PB170, "PowerBook 170", MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_PB170, "PowerBook 170", MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_OLD, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_PB180, "PowerBook 180", MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_PB180C, "PowerBook 180c", MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, - { MAC_MODEL_PB190, "PowerBook 190cs", MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_PB, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, + { MAC_MODEL_PB190, "PowerBook 190", MAC_ADB_PB1, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_PB, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, { MAC_MODEL_PB520, "PowerBook 520", MAC_ADB_PB2, MAC_VIA_QUADRA, MAC_SCSI_QUADRA, MAC_IDE_NONE, MAC_SCC_QUADRA, MAC_ETHER_NONE, MAC_NUBUS}, /* @@ -535,8 +560,8 @@ void mac_identify(void) printk (" Penguin bootinfo data:\n"); printk (" Video: addr 0x%lx row 0x%lx depth %lx dimensions %ld x %ld\n", mac_bi_data.videoaddr, mac_bi_data.videorow, - mac_bi_data.videodepth, (int) (mac_bi_data.dimensions & 0xFFFF), - (int) (mac_bi_data.dimensions >> 16)); + mac_bi_data.videodepth, mac_bi_data.dimensions & 0xFFFF, + mac_bi_data.dimensions >> 16); printk (" Videological 0x%lx phys. 0x%lx, SCC at 0x%lx \n", mac_bi_data.videological, mac_orig_videoaddr, mac_bi_data.sccbase); @@ -576,8 +601,7 @@ void mac_identify(void) break; } - - + via_configure_base(); } void mac_report_hardware(void) @@ -589,6 +613,8 @@ static void mac_get_model(char *str) { strcpy(str,"Macintosh "); strcat(str, macintosh_config->name); + if(mach_l2_flush && !(via_read(via2, vBufB)&VIA2B_vCDis)) + strcat(str, "(+L2 cache)"); } /* diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c index 6fc3ac52d..62a8a6187 100644 --- a/arch/m68k/mac/debug.c +++ b/arch/m68k/mac/debug.c @@ -249,7 +249,6 @@ void mac_boom(int booms) * TODO: serial debug code */ -#define SCC_BAS (0x50F04000) struct SCC { u_char cha_b_ctrl; @@ -260,7 +259,8 @@ struct SCC u_char char_dummy3; u_char cha_a_data; }; -# define scc ((*(volatile struct SCC*)SCC_BAS)) + +# define scc (*((volatile struct SCC*)mac_bi_data.sccbase)) /* Flag that serial port is already initialized and used */ int mac_SCC_init_done = 0; @@ -268,6 +268,8 @@ int mac_SCC_init_done = 0; * not be repeated; used by kgdb */ int mac_SCC_reset_done = 0; +static int scc_port = -1; + static struct console mac_console_driver = { "debug", NULL, /* write */ @@ -282,20 +284,18 @@ static struct console mac_console_driver = { NULL }; -static int scc_port; - /* Mac: loops_per_sec min. 1900000 ^= .5 us; MFPDELAY was 0.6 us*/ -#define US 1 +#define uSEC 1 static inline void mac_sccb_out (char c) { int i; do { - for( i = US; i > 0; --i ) + for( i = uSEC; i > 0; --i ) barrier(); } while (!(scc.cha_b_ctrl & 0x04)); /* wait for tx buf empty */ - for( i = US; i > 0; --i ) + for( i = uSEC; i > 0; --i ) barrier(); scc.cha_b_data = c; } @@ -304,10 +304,10 @@ static inline void mac_scca_out (char c) { int i; do { - for( i = US; i > 0; --i ) + for( i = uSEC; i > 0; --i ) barrier(); } while (!(scc.cha_a_ctrl & 0x04)); /* wait for tx buf empty */ - for( i = US; i > 0; --i ) + for( i = uSEC; i > 0; --i ) barrier(); scc.cha_a_data = c; } @@ -337,10 +337,10 @@ int mac_sccb_console_wait_key(struct console *co) { int i; do { - for( i = US; i > 0; --i ) + for( i = uSEC; i > 0; --i ) barrier(); } while( !(scc.cha_b_ctrl & 0x01) ); /* wait for rx buf filled */ - for( i = US; i > 0; --i ) + for( i = uSEC; i > 0; --i ) barrier(); return( scc.cha_b_data ); } @@ -349,10 +349,10 @@ int mac_scca_console_wait_key(struct console *co) { int i; do { - for( i = US; i > 0; --i ) + for( i = uSEC; i > 0; --i ) barrier(); } while( !(scc.cha_a_ctrl & 0x01) ); /* wait for rx buf filled */ - for( i = US; i > 0; --i ) + for( i = uSEC; i > 0; --i ) barrier(); return( scc.cha_a_data ); } @@ -365,10 +365,10 @@ int mac_scca_console_wait_key(struct console *co) do { \ int i; \ scc.cha_b_ctrl = (reg); \ - for( i = US; i > 0; --i ) \ + for( i = uSEC; i > 0; --i ) \ barrier(); \ scc.cha_b_ctrl = (val); \ - for( i = US; i > 0; --i ) \ + for( i = uSEC; i > 0; --i ) \ barrier(); \ } while(0) @@ -376,10 +376,10 @@ int mac_scca_console_wait_key(struct console *co) do { \ int i; \ scc.cha_a_ctrl = (reg); \ - for( i = US; i > 0; --i ) \ + for( i = uSEC; i > 0; --i ) \ barrier(); \ scc.cha_a_ctrl = (val); \ - for( i = US; i > 0; --i ) \ + for( i = uSEC; i > 0; --i ) \ barrier(); \ } while(0) @@ -389,7 +389,7 @@ int mac_scca_console_wait_key(struct console *co) #define LONG_DELAY() \ do { \ int i; \ - for( i = 60*US; i > 0; --i ) \ + for( i = 60*uSEC; i > 0; --i ) \ barrier(); \ } while(0) @@ -399,19 +399,21 @@ __initfunc(static void mac_init_scc_port( int cflag, int port )) void mac_init_scc_port( int cflag, int port ) #endif { - extern int mac_SCC_reset_done; - static int clksrc_table[9] = - /* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */ - { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }; - static int brgsrc_table[9] = - /* reg 14: 0 = RTxC, 2 = PCLK */ - { 2, 2, 2, 2, 2, 2, 0, 2, 2 }; - static int clkmode_table[9] = - /* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */ - { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 }; - static int div_table[9] = - /* reg12 (BRG low) */ - { 208, 138, 103, 50, 24, 11, 1, 0, 0 }; + extern int mac_SCC_reset_done; + + /* + * baud rates: 1200, 1800, 2400, 4800, 9600, 19.2k, 38.4k, 57.6k, 115.2k + */ + + static int clksrc_table[9] = + /* reg 11: 0x50 = BRG, 0x00 = RTxC, 0x28 = TRxC */ + { 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x00, 0x00 }; + static int clkmode_table[9] = + /* reg 4: 0x40 = x16, 0x80 = x32, 0xc0 = x64 */ + { 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0xc0, 0x80 }; + static int div_table[9] = + /* reg12 (BRG low) */ + { 94, 62, 46, 22, 10, 4, 1, 0, 0 }; int baud = cflag & CBAUD; int clksrc, clkmode, div, reg3, reg5; @@ -426,12 +428,10 @@ void mac_init_scc_port( int cflag, int port ) clkmode = clkmode_table[baud]; div = div_table[baud]; - reg3 = (cflag & CSIZE) == CS8 ? 0xc0 : 0x40; - reg5 = (cflag & CSIZE) == CS8 ? 0x60 : 0x20 | 0x82 /* assert DTR/RTS */; + reg3 = (((cflag & CSIZE) == CS8) ? 0xc0 : 0x40); + reg5 = (((cflag & CSIZE) == CS8) ? 0x60 : 0x20) | 0x82 /* assert DTR/RTS */; -#if 0 - if (port) { -#endif + if (port == 1) { (void)scc.cha_b_ctrl; /* reset reg pointer */ SCCB_WRITE( 9, 0xc0 ); /* reset */ LONG_DELAY(); /* extra delay after WR9 access */ @@ -442,17 +442,14 @@ void mac_init_scc_port( int cflag, int port ) SCCB_WRITE( 5, reg5 ); SCCB_WRITE( 9, 0 ); /* no interrupts */ LONG_DELAY(); /* extra delay after WR9 access */ - SCCB_WRITE( 10, 0 ); /* NRZ mode */ + SCCB_WRITE( 10, 0 ); /* NRZ mode */ SCCB_WRITE( 11, clksrc ); /* main clock source */ SCCB_WRITE( 12, div ); /* BRG value */ SCCB_WRITE( 13, 0 ); /* BRG high byte */ - SCCB_WRITE( 14, brgsrc_table[baud] ); - SCCB_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) ); + SCCB_WRITE( 14, 1 ); SCCB_WRITE( 3, reg3 | 1 ); SCCB_WRITE( 5, reg5 | 8 ); -#if 0 - } else { -#endif + } else if (port == 0) { (void)scc.cha_a_ctrl; /* reset reg pointer */ SCCA_WRITE( 9, 0xc0 ); /* reset */ LONG_DELAY(); /* extra delay after WR9 access */ @@ -463,17 +460,15 @@ void mac_init_scc_port( int cflag, int port ) SCCA_WRITE( 5, reg5 ); SCCA_WRITE( 9, 0 ); /* no interrupts */ LONG_DELAY(); /* extra delay after WR9 access */ - SCCA_WRITE( 10, 0 ); /* NRZ mode */ + SCCA_WRITE( 10, 0 ); /* NRZ mode */ SCCA_WRITE( 11, clksrc ); /* main clock source */ SCCA_WRITE( 12, div ); /* BRG value */ SCCA_WRITE( 13, 0 ); /* BRG high byte */ - SCCA_WRITE( 14, brgsrc_table[baud] ); - SCCA_WRITE( 14, brgsrc_table[baud] | (div ? 1 : 0) ); + SCCA_WRITE( 14, 1 ); SCCA_WRITE( 3, reg3 | 1 ); SCCA_WRITE( 5, reg5 | 8 ); -#if 0 } -#endif + mac_SCC_reset_done = 1; mac_SCC_init_done = 1; } @@ -486,18 +481,20 @@ __initfunc(void mac_debug_init(void)) return; #endif #ifdef DEBUG_SERIAL - if (!strcmp( m68k_debug_device, "ser" )) { - strcpy( m68k_debug_device, "ser1" ); - } - if (!strcmp( m68k_debug_device, "ser1" )) { - /* ST-MFP Modem1 serial port */ + if ( !strcmp( m68k_debug_device, "ser" ) + || !strcmp( m68k_debug_device, "ser1" )) { + /* Mac modem port */ mac_init_scc_port( B9600|CS8, 0 ); mac_console_driver.write = mac_scca_console_write; + mac_console_driver.wait_key = mac_scca_console_wait_key; + scc_port = 0; } else if (!strcmp( m68k_debug_device, "ser2" )) { - /* SCC Modem2 serial port */ + /* Mac printer port */ mac_init_scc_port( B9600|CS8, 1 ); mac_console_driver.write = mac_sccb_console_write; + mac_console_driver.wait_key = mac_sccb_console_wait_key; + scc_port = 1; } if (mac_console_driver.write) register_console(&mac_console_driver); diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c index d24c5ae16..95078a384 100644 --- a/arch/m68k/mac/macboing.c +++ b/arch/m68k/mac/macboing.c @@ -27,12 +27,52 @@ void mac_mksound( unsigned int hz, unsigned int ticks ) unsigned long flags; int samples=512; + if (macintosh_config->ident == MAC_MODEL_C660 + || macintosh_config->ident == MAC_MODEL_Q840) + { + /* + * The Quadra 660AV and 840AV use the "Singer" custom ASIC for sound I/O. + * It appears to be similar to the "AWACS" custom ASIC in the Power Mac + * [678]100. Because Singer and AWACS may have a similar hardware + * interface, this would imply that the code in drivers/sound/dmasound.c + * for AWACS could be used as a basis for Singer support. All we have to + * do is figure out how to do DMA on the 660AV/840AV through the PSC and + * figure out where the Singer hardware sits in memory. (I'd look in the + * vicinity of the AWACS location in a Power Mac [678]100 first, or the + * current location of the Apple Sound Chip--ASC--in other Macs.) The + * Power Mac [678]100 info can be found in MkLinux Mach kernel sources. + * + * Quoted from Apple's Tech Info Library, article number 16405: + * "Among desktop Macintosh computers, only the 660AV, 840AV, and Power + * Macintosh models have 16-bit audio input and output capability + * because of the AT&T DSP3210 hardware circuitry and the 16-bit Singer + * codec circuitry in the AVs. The Audio Waveform Amplifier and + * Converter (AWAC) chip in the Power Macintosh performs the same + * 16-bit I/O functionality. The PowerBook 500 series computers + * support 16-bit stereo output, but only mono input." + * + * http://til.info.apple.com/techinfo.nsf/artnum/n16405 + * + * --David Kilzer + */ + + return; + } + if(!inited) { int i=0; int j=0; int k=0; int l=0; + + /* + * The IIfx strikes again! + */ + + if(macintosh_config->ident==MAC_MODEL_IIFX) + asc_base=(void *)0x50010000; + for(i=0;i<samples;i++) { asc_base[i]=sine_data[j]; diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c index d2ea26e05..b703cb275 100644 --- a/arch/m68k/mac/macints.c +++ b/arch/m68k/mac/macints.c @@ -216,7 +216,10 @@ void mac_debug_handler(int irq, void *dev_id, struct pt_regs *regs); static void via_do_nubus(int slot, void *via, struct pt_regs *regs); -/*#define DEBUG_VIA*/ +/* #define DEBUG_MACINTS */ +/* #define DEBUG_NUBUS_INT */ +/* #define DEBUG_VIA */ +/* #define DEBUG_VIA_NUBUS */ void mac_init_IRQ(void) { @@ -273,13 +276,8 @@ void mac_init_IRQ(void) * Currently, one interrupt per channel is used, solely * to pass the correct async_info as parameter! */ -#if 0 /* want to install debug/SCC shutup routine until SCC init */ - sys_request_irq(4, mac_SCC_handler, IRQ_FLG_STD, "INT4", mac_SCC_handler); -#else + sys_request_irq(4, mac_debug_handler, IRQ_FLG_STD, "INT4", mac_debug_handler); -#endif - /* Alan uses IRQ 5 for SCC ?? */ - sys_request_irq(5, mac_debug_handler, IRQ_FLG_STD, "INT5", mac_debug_handler); /* level 6 */ sys_request_irq(6, mac_bang, IRQ_FLG_LOCK, "offswitch", mac_bang); @@ -289,25 +287,25 @@ void mac_init_IRQ(void) /* initialize the handler tables for VIAs */ for (i = 0; i < 8; i++) { - via1_handler[i].handler = mac_default_handler; - via1_handler[i].dev_id = NULL; - via1_param[i].flags = IRQ_FLG_STD; - via1_param[i].devname = NULL; - - via2_handler[i].handler = mac_default_handler; - via2_handler[i].dev_id = NULL; - via2_param[i].flags = IRQ_FLG_STD; - via2_param[i].devname = NULL; - - rbv_handler[i].handler = mac_default_handler; - rbv_handler[i].dev_id = NULL; - rbv_param[i].flags = IRQ_FLG_STD; - rbv_param[i].devname = NULL; - - scc_handler[i].handler = mac_default_handler; - scc_handler[i].dev_id = NULL; - scc_param[i].flags = IRQ_FLG_STD; - scc_param[i].devname = NULL; + via1_handler[i].handler = mac_default_handler; + via1_handler[i].dev_id = NULL; + via1_param[i].flags = IRQ_FLG_STD; + via1_param[i].devname = NULL; + + via2_handler[i].handler = mac_default_handler; + via2_handler[i].dev_id = NULL; + via2_param[i].flags = IRQ_FLG_STD; + via2_param[i].devname = NULL; + + rbv_handler[i].handler = mac_default_handler; + rbv_handler[i].dev_id = NULL; + rbv_param[i].flags = IRQ_FLG_STD; + rbv_param[i].devname = NULL; + + scc_handler[i].handler = mac_default_handler; + scc_handler[i].dev_id = NULL; + scc_param[i].flags = IRQ_FLG_STD; + scc_param[i].devname = NULL; /* NUBUS interrupts routed through VIA2 slot 2 - special */ nubus_handler[i].handler = nubus_wtf; @@ -337,16 +335,16 @@ void mac_init_IRQ(void) via_table[2] = NULL; via_table[3] = NULL; - handler_table[2] = &rbv_handler[0]; + handler_table[2] = &rbv_handler[0]; handler_table[3] = &scc_handler[0]; handler_table[4] = NULL; handler_table[5] = NULL; handler_table[6] = NULL; - handler_table[7] = &nubus_handler[0]; + handler_table[7] = &nubus_handler[0]; - param_table[2] = &rbv_param[0]; + param_table[2] = &rbv_param[0]; param_table[3] = &scc_param[0]; - param_table[7] = &nubus_param[0]; + param_table[7] = &nubus_param[0]; mac_irqs[2] = &rbv_irqs[0]; mac_irqs[3] = &scc_irqs[0]; @@ -356,7 +354,8 @@ void mac_init_IRQ(void) * AV Macs: shutup the PSC ints */ if (macintosh_config->ident == MAC_MODEL_C660 - || macintosh_config->ident == MAC_MODEL_Q840) { + || macintosh_config->ident == MAC_MODEL_Q840) + { psc_init(); handler_table[2] = &psc3_handler[0]; @@ -463,9 +462,15 @@ int mac_request_irq (unsigned int irq, void (*handler)(int, void *, struct pt_re * 980429 MS: RBV is ok, OSS seems to be differentt */ if (!via2_is_oss) - /* CB2 (IRQ) indep. interrupt input, positive edge */ - /* CA2 (DRQ) indep. interrupt input, positive edge */ - via_write(via, vPCR, 0x66); + if (macintosh_config->scsi_type == MAC_SCSI_OLD) { + /* CB2 (IRQ) indep. interrupt input, positive edge */ + /* CA2 (DRQ) indep. interrupt input, positive edge */ + via_write(via, vPCR, 0x66); + } else { + /* CB2 (IRQ) indep. interrupt input, negative edge */ + /* CA2 (DRQ) indep. interrupt input, negative edge */ + via_write(via, vPCR, 0x22); + } #if 0 else /* CB2 (IRQ) indep. interrupt input, negative edge */ @@ -614,7 +619,7 @@ void mac_turnon_irq( unsigned int irq ) via_write(via, rIER, via_read(via, rIER)|0x80|(1<<(irqidx))); else if (srcidx == SRC_VIA2 && via2_is_oss) via_write(oss_regp, oss_map[irqidx]+8, 2); - else if (srcidx >= SRC_VIA2) + else if (srcidx > SRC_VIA2) via_write(via, (0x104 + 0x10*srcidx), via_read(via, (0x104 + 0x10*srcidx))|0x80|(1<<(irqidx))); else @@ -636,7 +641,11 @@ void mac_turnoff_irq( unsigned int irq ) via_write(via, rIER, (via_read(via, rIER)&(1<<irqidx))); else if (srcidx == SRC_VIA2 && via2_is_oss) via_write(oss_regp, oss_map[irqidx]+8, 0); - else if (srcidx >= SRC_VIA2) + /* + * VIA2 is fixed. The stuff above VIA2 is for later + * macintoshes only. + */ + else if (srcidx > SRC_VIA2) via_write(via, (0x104 + 0x10*srcidx), via_read(via, (0x104 + 0x10*srcidx))|(1<<(irqidx))); else @@ -677,7 +686,7 @@ int mac_irq_pending( unsigned int irq ) pending |= via_read(via, rIFR)&(1<<irqidx); else if (srcidx == SRC_VIA2 && via2_is_oss) pending |= via_read(via, oIFR)&0x03&(1<<oss_map[irqidx]); - else if (srcidx >= SRC_VIA2) + else if (srcidx > SRC_VIA2) pending |= via_read(via, (0x100 + 0x10*srcidx))&(1<<irqidx); else pending |= via_read(via, vIFR)&(1<<irqidx); @@ -1159,7 +1168,7 @@ void oss_irq(int irq, void *dev_id, struct pt_regs *regs) * limited verbosity for RBV interrupts (add more if needed) */ if ( events != 1<<3 ) /* SCSI IRQ */ - printk("oss_irq: irq %d events %x %x %x !\n", irq, srcidx+1, + printk("oss_irq: irq %d srcidx+1 %d events %x %x %x !\n", irq, srcidx+1, events, adb_ev, nub_ev); #endif @@ -1313,7 +1322,7 @@ void psc_irq(int irq, void *dev_id, struct pt_regs *regs) * limited verbosity for RBV interrupts (add more if needed) */ if ( srcidx == 1 && events != 1<<3 && events != 1<<1 ) /* SCSI IRQ */ - printk("psc_irq: irq %d events %x !\n", irq, srcidx+1, events); + printk("psc_irq: irq %d srcidx+1 %d events %x !\n", irq, srcidx+1, events); #endif /* to be changed, possibly: for each non'masked', enabled IRQ, read diff --git a/arch/m68k/mac/mackeyb.c b/arch/m68k/mac/mackeyb.c index fa529e29e..64cd5e1f8 100644 --- a/arch/m68k/mac/mackeyb.c +++ b/arch/m68k/mac/mackeyb.c @@ -51,6 +51,7 @@ static void input_keycode(int, int); extern struct kbd_struct kbd_table[]; +extern void adb_bus_init(void); extern void handle_scancode(unsigned char); extern void put_queue(int); @@ -59,9 +60,9 @@ static void mac_leds_done(struct adb_request *); static void keyboard_input(unsigned char *, int, struct pt_regs *); static void mouse_input(unsigned char *, int, struct pt_regs *); /* Hook for mouse driver */ -void (*adb_mouse_interrupt_hook) (unsigned char *, int); +void (*adb_mouse_interrupt_hook) (char *, int); /* The mouse driver - for debugging */ -extern void mac_mouse_interrupt(char *); +extern void adb_mouse_interrupt(char *, int); /* end keyb */ /* this map indicates which keys shouldn't autorepeat. */ @@ -652,6 +653,8 @@ __initfunc(int mac_keyb_init(void)) printk("Configuring keyboard:\n"); + udelay(3000); + /* * turn on all leds - the keyboard driver will turn them back off * via mac_kbd_leds if everything works ok! @@ -676,6 +679,8 @@ __initfunc(int mac_keyb_init(void)) #if 1 printk("configuring coding mode ...\n"); + udelay(3000); + /* * get the keyboard to send separate codes for * left and right shift, control, option keys. @@ -697,6 +702,8 @@ __initfunc(int mac_keyb_init(void)) #if 0 /* seems to hurt, at least Geert's Mac */ printk("Configuring mouse (3-button mode) ...\n"); + udelay(3000); + /* * XXX: taken from the PPC driver again ... * Try to switch the mouse (id 3) to handler 4, for three-button @@ -738,8 +745,3 @@ __initfunc(int mac_keyb_init(void)) __initfunc(void mac_kbd_reset_setup(char *str, int *ints)) { } - -/* for "kbd-reset" cmdline param */ -__initfunc(void mac_kbd_reset_setup(char *str, int *ints)) -{ -} diff --git a/arch/m68k/mac/psc.h b/arch/m68k/mac/psc.h deleted file mode 100644 index 964f6547c..000000000 --- a/arch/m68k/mac/psc.h +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Apple Peripheral System Controller (PSC) - * - * The PSC is used on the AV Macs to control IO functions not handled - * by the VIAs (Ethernet, DSP, SCC). - */ - -#define PSCBASE 0x50F31000 - -#define pIFR3 0x130 -#define pIFR4 0x140 -#define pIFR5 0x150 -#define pIFR6 0x160 - -#define pIER3 0x134 -#define pIER4 0x144 -#define pIER5 0x154 -#define pIER6 0x164 diff --git a/arch/m68k/mac/via6522.c b/arch/m68k/mac/via6522.c index c867bc96d..08ca49071 100644 --- a/arch/m68k/mac/via6522.c +++ b/arch/m68k/mac/via6522.c @@ -8,16 +8,21 @@ #include <linux/types.h> #include <linux/kernel.h> #include <linux/mm.h> +#include <linux/delay.h> +#include <asm/adb.h> +#include <asm/bootinfo.h> #include <asm/macintosh.h> #include <asm/macints.h> #include "via6522.h" -#include "psc.h" +#include <asm/mac_psc.h> volatile unsigned char *via1=(unsigned char *)VIABASE; volatile unsigned char *via2=(unsigned char *)VIABASE2; volatile unsigned char *psc=(unsigned char *)PSCBASE; +volatile long *via_memory_bogon=(long *)&via_memory_bogon; + unsigned char via1_clock, via1_datab; static int rbv=0; @@ -38,9 +43,8 @@ static void (*rom_reset)(void); #define MAC_CLOCK_HIGH (MAC_CLOCK_TICK>>8) -void via_init_clock(void (*func)(int, void *, struct pt_regs *)) +void via_configure_base(void) { - unsigned char c; switch(macintosh_config->via_type) { @@ -66,6 +70,13 @@ void via_init_clock(void (*func)(int, void *, struct pt_regs *)) break; default: } +} + + +void via_init_clock(void (*func)(int, void *, struct pt_regs *)) +{ + unsigned char c; + via1_clock=via_read(via1, vACR); via1_datab=via_read(via1, vBufB); @@ -179,29 +190,28 @@ void via_init_clock(void (*func)(int, void *, struct pt_regs *)) } /* - * get time offset between scheduling timer ticks - * Code stolen from arch/m68k/atari/time.c; underflow check probably - * wrong. + * TBI: get time offset between scheduling timer ticks */ #define TICK_SIZE 10000 /* This is always executed with interrupts disabled. */ + unsigned long mac_gettimeoffset (void) { - unsigned long ticks, offset = 0; + unsigned long ticks, offset = 0; - /* read VIA1 timer 2 current value */ - ticks = via_read(via1, vT1CL) + (via_read(via1, vT1CH)<<8); - /* The probability of underflow is less than 2% */ - if (ticks > MAC_CLOCK_TICK - MAC_CLOCK_TICK / 50) - /* Check for pending timer interrupt in VIA1 IFR */ - if (via_read(via1, vIFR) & 0x40) - offset = TICK_SIZE; + /* read VIA1 timer 2 current value */ + ticks = via_read(via1, vT1CL) + (via_read(via1, vT1CH)<<8); + /* The probability of underflow is less than 2% */ + if (ticks > MAC_CLOCK_TICK - MAC_CLOCK_TICK / 50) + /* Check for pending timer interrupt in VIA1 IFR */ + if (via_read(via1, vIFR) & 0x40) + offset = TICK_SIZE; - ticks = MAC_CLOCK_TICK - ticks; - ticks = ticks * 10000L / MAC_CLOCK_TICK; + ticks = MAC_CLOCK_TICK - ticks; + ticks = ticks * 10000L / MAC_CLOCK_TICK; - return ticks + offset; + return ticks + offset; } /* @@ -218,27 +228,64 @@ void psc_init(void) } /* - * The power switch - yes its software! + * The power switch - yes it's software! */ - + void mac_poweroff(void) { -#if 0 + /* - * Powerdown, for the Macs that support it + * MAC_ADB_IISI may need to be moved up here if it doesn't actually + * work using the ADB packet method. --David Kilzer */ - if(rbv) { - via_write(via2, rBufB, via_read(via2, rBufB)&~0x04); - } else { - /* Direction of vDirB is output */ - via_write(via2,vDirB,via_read(via2,vDirB)|0x04); - /* Send a value of 0 on that line */ - via_write(via2,vBufB,via_read(via2,vBufB)&~0x04); + + if (macintosh_config->adb_type == MAC_ADB_II) + { + if(rbv) { + via_write(via2, rBufB, via_read(via2, rBufB)&~0x04); + } else { + /* Direction of vDirB is output */ + via_write(via2,vDirB,via_read(via2,vDirB)|0x04); + /* Send a value of 0 on that line */ + via_write(via2,vBufB,via_read(via2,vBufB)&~0x04); + /* Otherwise it prints "It is now.." then shuts off */ + mdelay(1000); + } + + /* We should never make it this far... */ + printk ("It is now safe to switch off your machine.\n"); + + /* XXX - delay do we need to spin here ? */ + while(1); /* Just in case .. */ + } + + /* + * Initially discovered this technique in the Mach kernel of MkLinux in + * osfmk/src/mach_kernel/ppc/POWERMAC/cuda_power.c. Found equivalent LinuxPPC + * code in arch/ppc/kernel/setup.c, which also has a PMU technique for PowerBooks! + * --David Kilzer + */ + + else if (macintosh_config->adb_type == MAC_ADB_IISI + || macintosh_config->adb_type == MAC_ADB_CUDA) + { + struct adb_request req; + + /* + * Print our "safe" message before we send the request + * just in case the request never returns. + */ + + printk ("It is now safe to switch off your machine.\n"); + + adb_request (&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN); + + printk ("ADB powerdown request sent.\n"); + for (;;) + { + adb_poll(); + } } -#endif - /* We should never make it this far... */ - /* XXX - delay do we need to spin here ? */ - while(1); /* Just in case .. */ } /* @@ -247,28 +294,65 @@ void mac_poweroff(void) */ void mac_reset(void) { - unsigned long flags; - unsigned long *reset_hook; - - save_flags(flags); - cli(); - -#if 0 /* need ROMBASE in booter */ -#if 0 /* works on some */ - rom_reset = (boot_info.bi_mac.rombase + 0xa); -#else /* testing, doesn't work on SE/30 either */ - reset_hook = (unsigned long *) (boot_info.bi_mac.rombase + 0x4); - printk("ROM reset hook: %p\n", *reset_hook); - rom_reset = *reset_hook; -#endif - rom_reset(); + /* + * MAC_ADB_IISI may need to be moved up here if it doesn't actually + * work using the ADB packet method. --David Kilzer + */ + + if (macintosh_config->adb_type == MAC_ADB_II) + { + unsigned long flags; + unsigned long *reset_hook; + + save_flags(flags); + cli(); + + /* need ROMBASE in booter */ + + /* works on some */ + rom_reset = (void *) (mac_bi_data.rombase + 0xa); + +#if 0 + /* testing, doesn't work on SE/30 either */ + reset_hook = (unsigned long *) (mac_bi_data.rombase + 0x4); + printk("ROM reset hook: %p\n", *reset_hook); + rom_reset = *reset_hook; #endif - restore_flags(flags); - /* We never make it this far... */ - printk(" reboot failed, reboot manually!\n"); - /* XXX - delay do we need to spin here ? */ - while(1); /* Just in case .. */ + rom_reset(); + + restore_flags(flags); + + /* We never make it this far... */ + printk ("Restart failed. Please restart manually.\n"); + + /* XXX - delay do we need to spin here ? */ + while(1); /* Just in case .. */ + } + + /* + * Initially discovered this technique in the Mach kernel of MkLinux in + * osfmk/src/mach_kernel/ppc/POWERMAC/cuda_power.c. Found equivalent LinuxPPC + * code in arch/ppc/kernel/setup.c, which also has a PMU technique! + * --David Kilzer + * + * I suspect the MAC_ADB_CUDA code might work with other ADB types of machines + * but have no way to test this myself. --DDK + */ + + else if (macintosh_config->adb_type == MAC_ADB_IISI + || macintosh_config->adb_type == MAC_ADB_CUDA) + { + struct adb_request req; + + adb_request (&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM); + + printk ("Restart failed. Please restart manually.\n"); + for (;;) + { + adb_poll(); + } + } } /* diff --git a/arch/m68k/mac/via6522.h b/arch/m68k/mac/via6522.h index fa8a3ff76..91ba1d58e 100644 --- a/arch/m68k/mac/via6522.h +++ b/arch/m68k/mac/via6522.h @@ -6,6 +6,9 @@ * is a bit incomplete as the Mac documentation doesnt cover this well */ +#ifndef _ASM_VIA6522_H_ +#define _ASM_VIA6522_H_ + #define VIABASE 0x50F00000 #define VIABASE2 0x50F02000 @@ -45,17 +48,32 @@ * Register B has the fun stuff in it */ +#define VIA2B_vMode32 0x08 /* 24/32bit switch - doubles as cache flush */ #define VIA2B_vPower 0x04 /* Off switch */ -#define VIA2B_vBusLk 0x02 -#define VIA2B_vCDis 0x01 +#define VIA2B_vBusLk 0x02 /* Nubus in use ?? */ +#define VIA2B_vCDis 0x01 /* Cache disable */ + +/* + * The 6522 via is a 2MHz part, and needs a delay. MacOS seems to + * execute MOV (Ax),(Ax) for this... Oh and we can't use udelay + * here... see we need the via to calibrate the udelay loop ... + */ +extern volatile long *via_memory_bogon; + extern __inline__ void via_write(volatile unsigned char *via,int reg, int v) { + *via_memory_bogon; + *via_memory_bogon; + *via_memory_bogon; via[reg]=v; } extern __inline__ int via_read(volatile unsigned char *via,int reg) { + *via_memory_bogon; + *via_memory_bogon; + *via_memory_bogon; return (int)via[reg]; } @@ -109,3 +127,5 @@ extern void via1_irq(int, void *, struct pt_regs *); extern void via2_irq(int, void *, struct pt_regs *); extern void via_setup_keyboard(void); + +#endif /* _ASM_VIA6522_H_ */ diff --git a/arch/m68k/mm/memory.c b/arch/m68k/mm/memory.c index fb13d8257..39cc1d1a9 100644 --- a/arch/m68k/mm/memory.c +++ b/arch/m68k/mm/memory.c @@ -18,6 +18,7 @@ #include <asm/system.h> #include <asm/traps.h> #include <asm/io.h> +#include <asm/machdep.h> #ifdef CONFIG_AMIGA #include <asm/amigahw.h> #endif @@ -554,6 +555,14 @@ unsigned long mm_ptov (unsigned long paddr) * this?). So we have to push first and then additionally to invalidate. */ +#ifdef CONFIG_M68K_L2_CACHE +/* + * Jes was worried about performance (urhh ???) so its optional + */ + +extern void (*mach_l2_flush)(int) = NULL; +#endif + /* * cache_clear() semantics: Clear any cache entries for the area in question, * without writing back dirty entries first. This is useful if the data will @@ -593,6 +602,10 @@ void cache_clear (unsigned long paddr, int len) "movec %/d0,%/cacr" : : "i" (FLUSH_I_AND_D) : "d0"); +#ifdef CONFIG_M68K_L2_CACHE + if(mach_l2_flush) + mach_l2_flush(0); +#endif } @@ -641,6 +654,10 @@ void cache_push (unsigned long paddr, int len) "movec %/d0,%/cacr" : : "i" (FLUSH_I) : "d0"); +#ifdef CONFIG_M68K_L2_CACHE + if(mach_l2_flush) + mach_l2_flush(1); +#endif } |