summaryrefslogtreecommitdiffstats
path: root/arch/m68k
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1999-01-03 17:49:53 +0000
committerRalf Baechle <ralf@linux-mips.org>1999-01-03 17:49:53 +0000
commiteb7a5bf93aaa4be1d7c6181100ab7639e74d67f7 (patch)
tree5746fea1605ff013be9b78a1556aaad7615d664a /arch/m68k
parent80ea5b1e15398277650e1197957053b5a71c08bc (diff)
Merge with Linux 2.1.131 plus some more MIPS goodies.
Diffstat (limited to 'arch/m68k')
-rw-r--r--arch/m68k/amiga/amiints.c2
-rw-r--r--arch/m68k/amiga/config.c22
-rw-r--r--arch/m68k/atari/ataints.c10
-rw-r--r--arch/m68k/atari/stram.c259
-rw-r--r--arch/m68k/atari/time.c3
-rw-r--r--arch/m68k/config.in13
-rw-r--r--arch/m68k/kernel/entry.S2
-rw-r--r--arch/m68k/kernel/m68k_defs.h6
-rw-r--r--arch/m68k/kernel/m68k_ksyms.c5
-rw-r--r--arch/m68k/kernel/ptrace.c8
-rw-r--r--arch/m68k/kernel/traps.c2
-rw-r--r--arch/m68k/mac/adb-bus.c5
-rw-r--r--arch/m68k/mac/config.c86
-rw-r--r--arch/m68k/mac/debug.c103
-rw-r--r--arch/m68k/mac/macboing.c40
-rw-r--r--arch/m68k/mac/macints.c87
-rw-r--r--arch/m68k/mac/mackeyb.c16
-rw-r--r--arch/m68k/mac/psc.h18
-rw-r--r--arch/m68k/mac/via6522.c188
-rw-r--r--arch/m68k/mac/via6522.h24
-rw-r--r--arch/m68k/mm/memory.c17
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
}