Subject: README: Please give this a try!
To: None <port-mac68k@NetBSD.ORG>
From: Scott Reynolds <scottr@og.org>
List: port-mac68k
Date: 05/20/1998 02:11:52
i would appreciate any testing that folks can reasonably do by the end of
the week on this change. please submit any feedback that you may have by
saturday evening directly to me. (this is important: mail to the list
has a lower priority than mail sent directly to me!)
what it is:
this is a change to (hopefully) once and for all kill the problems that
people seem to have with rebooting.
the old way:
map the ROM into the space it likes to be, then jump to the ROM reset with
our fingers crossed.
the new way:
map a single page at the end of physical RAM such that the virtual address
equals the physical address. copy code to disable the MMU and jump to the
ROM reset into this page, then jump to the code we just copied.
my analysis:
the old way has a fatal flaw. it might be reassigning a page that the
kernel really wants to have around, particularly a page table page or
other vm/pmap structure. the new way maps a single page that's reserved
at boot time, minimizing the chance that we'll run into problems later on.
note that i'm also addressing a problem where the startup process fails to
determine the cpu/fpu/mmu types. that generally doesn't happen, but it
led to... unpredictable results.
this has so far worked on a wide range of systems, from original II-series
to IIci-class to several performa and quadra systems. however, i'd like
to see as much testing done as possible before this one goes into mthe
tree. any feedback will be most appreciated, even if it's to say my
analysis is flawed in itself. :-}
--scott
!! this patch is intended to be applied against NetBSD-current source.
it _will_not_ work without modification on a 1.3 or 1.3.1 source
tree.
Index: locore.s
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/mac68k/locore.s,v
retrieving revision 1.97
diff -c -r1.97 locore.s
*** locore.s 1998/04/24 05:27:25 1.97
--- locore.s 1998/05/11 05:33:46
***************
*** 131,136 ****
--- 131,148 ----
movc d0,sfc | as source
movc d0,dfc | and destination of transfers
+ /*
+ * Some parameters provided by MacOS
+ *
+ * LAK: This section is the new way to pass information from the booter
+ * to the kernel. At A1 there is an environment variable which has
+ * a bunch of stuff in ascii format, "VAR=value\0VAR=value\0\0".
+ */
+ movl a1,sp@- | Address of buffer
+ movl d4,sp@- | Some flags... (mostly not used)
+ jbsr _C_LABEL(getenvvars) | Parse the environment buffer
+ addql #8,sp
+
/* Determine MMU/MPU from what we can test empirically */
movl #0x200,d0 | data freeze bit
movc d0,cacr | only exists on 68030
***************
*** 200,216 ****
jra Ldoboot1
Lstart2:
- /*
- * Some parameters provided by MacOS
- *
- * LAK: This section is the new way to pass information from the booter
- * to the kernel. At A1 there is an environment variable which has
- * a bunch of stuff in ascii format, "VAR=value\0VAR=value\0\0".
- */
- movl a1,sp@- | Address of buffer
- movl d4,sp@- | Some flags... (mostly not used)
- jbsr _C_LABEL(getenvvars) | Parse the environment buffer
- addql #8,sp
jbsr _C_LABEL(setmachdep) | Set some machine-dep stuff
jbsr _C_LABEL(consinit) | XXX Should only be if graybar on
--- 212,217 ----
***************
*** 1587,1619 ****
/*
* Handle the nitty-gritty of rebooting the machine.
! * Basically we just jump to the appropriate ROM routine after mapping
! * the ROM into its proper home (back in machdep).
*/
ENTRY_NOPROFILE(doboot)
! movw #PSL_HIGHIPL,sr | no interrupts
!
cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
! jne Ldobootnot040 | yes, skip
! movl #CACHE40_OFF,d0 | 68040 cache disable
! movc d0, cacr
! .word 0xf4f8 | cpusha bc - push and invalidate caches
! jra Ldoboot1
!
! Ldobootnot040:
movl #CACHE_OFF,d0
movc d0,cacr | disable on-chip cache(s)
! #ifdef __notyet__
! tstl _C_LABEL(ectype) | external cache?
! jeq Ldoboot1 | no, skip
! | Disable external cache here.
#endif
Ldoboot1:
! movl _C_LABEL(MacOSROMBase),_C_LABEL(ROMBase) | Load MacOS ROMBase
! movl #0x90,a1 | offset of ROM reset routine
! addl _C_LABEL(ROMBase),a1 | add to ROM base
! jra a1@ | and jump to ROM to reset machine
/*
* u_long ptest040(caddr_t addr, u_int fc);
--- 1588,1642 ----
/*
* Handle the nitty-gritty of rebooting the machine.
! * Basically we just turn off the MMU and jump to the appropriate ROM routine.
! * Note that we must be running in an address range that is mapped one-to-one
! * logical to physical so that the PC is still valid immediately after the MMU
! * is turned off. We have conveniently mapped the last page of physical
! * memory this way.
*/
ENTRY_NOPROFILE(doboot)
! #if defined(M68040)
cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
! jeq Lnocache5 | yes, skip
! #endif
movl #CACHE_OFF,d0
movc d0,cacr | disable on-chip cache(s)
! Lnocache5:
! movl _C_LABEL(maxaddr),a0 | last page of physical memory
! lea Lbootcode,a1 | start of boot code
! lea Lebootcode,a3 | end of boot code
! Lbootcopy:
! movw a1@+,a0@+ | copy a word
! cmpl a3,a1 | done yet?
! jcs Lbootcopy | no, keep going
! #if defined(M68040)
! cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
! jne LmotommuE | no, skip
! .word 0xf4f8 | cpusha bc
! LmotommuE:
! #endif
! movl _C_LABEL(maxaddr),a0
! jmp a0@ | jump to last page
!
! Lbootcode:
! lea a0@(0x800),sp | physical SP in case of NMI
! #if defined(M68040)
! cmpl #MMU_68040,_C_LABEL(mmutype) | 68040?
! jne LmotommuF | no, skip
! movl #0,d0
! movc d0,cacr | caches off
! .long 0x4e7b0003 | movc d0,tc (disable MMU)
! jra Ldoboot1
! LmotommuF:
#endif
+ movl #0,a3@ | value for pmove to TC (turn off MMU)
+ pmove a3@,tc | disable MMU
Ldoboot1:
! movl _C_LABEL(MacOSROMBase),a1 | Load MacOS ROMBase
! lea a1@(0x90),a1 | offset of ROM reset routine
! jmp a1@ | and jump to ROM to reset machine
! Lebootcode:
/*
* u_long ptest040(caddr_t addr, u_int fc);
Index: machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/mac68k/machdep.c,v
retrieving revision 1.195
diff -c -r1.195 machdep.c
*** machdep.c 1998/05/05 06:48:52 1.195
--- machdep.c 1998/05/08 09:19:31
***************
*** 706,712 ****
int howto;
char *bootstr;
{
! extern u_long MacOSROMBase;
extern int cold;
#if __GNUC__ /* XXX work around lame compiler problem (gcc 2.7.2) */
--- 706,712 ----
int howto;
char *bootstr;
{
! extern u_long maxaddr;
extern int cold;
#if __GNUC__ /* XXX work around lame compiler problem (gcc 2.7.2) */
***************
*** 767,778 ****
(void)cngetc();
}
! /*
! * Map ROM where the MacOS likes it, so we can reboot,
! * hopefully.
! */
! pmap_map(MacOSROMBase, MacOSROMBase, MacOSROMBase + 4 * 1024 * 1024,
! VM_PROT_READ | VM_PROT_WRITE | VM_PROT_EXECUTE);
printf("rebooting...\n");
DELAY(1000000);
--- 767,775 ----
(void)cngetc();
}
! /* Map the last physical page VA = PA for doboot() */
! pmap_enter(pmap_kernel(), (vm_offset_t)maxaddr, (vm_offset_t)maxaddr,
! VM_PROT_ALL, TRUE);
printf("rebooting...\n");
DELAY(1000000);
***************
*** 1295,1300 ****
--- 1292,1302 ----
(flag & 0x40000)) && bootdev == 0)
bootdev = MAKEBOOTDEV(4, 0, 0, root_scsi_id, 0);
+ /*
+ * Booter 1.11.3 and later pass a BOOTHOWTO variable with the
+ * appropriate bits set.
+ */
+ boothowto = getenv("BOOTHOWTO");
if (boothowto == 0)
boothowto = getenv("SINGLE_USER");
Index: pmap_bootstrap.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/mac68k/pmap_bootstrap.c,v
retrieving revision 1.42
diff -c -r1.42 pmap_bootstrap.c
*** pmap_bootstrap.c 1998/04/26 03:59:18 1.42
--- pmap_bootstrap.c 1998/05/08 09:19:33
***************
*** 64,70 ****
extern st_entry_t *Sysseg;
extern pt_entry_t *Sysptmap, *Sysmap;
! extern int maxmem, physmem;
extern int avail_remaining, avail_range, avail_end;
extern vm_offset_t avail_start, avail_next;
extern vm_offset_t virtual_avail, virtual_end;
--- 64,70 ----
extern st_entry_t *Sysseg;
extern pt_entry_t *Sysptmap, *Sysmap;
! extern int physmem;
extern int avail_remaining, avail_range, avail_end;
extern vm_offset_t avail_start, avail_next;
extern vm_offset_t virtual_avail, virtual_end;
***************
*** 76,84 ****
/*
* These are used to map the RAM:
*/
! int numranges; /* = 0 == don't use the ranges */
u_long low[8];
u_long high[8];
int vidlen;
#define VIDMAPSIZE btoc(vidlen)
extern u_int32_t mac68k_vidlog;
--- 76,85 ----
/*
* These are used to map the RAM:
*/
! int numranges; /* = 0 == don't use the ranges */
u_long low[8];
u_long high[8];
+ u_long maxaddr; /* PA of the last physical page */
int vidlen;
#define VIDMAPSIZE btoc(vidlen)
extern u_int32_t mac68k_vidlog;
***************
*** 317,323 ****
*pte = lkptpa | PG_RW | PG_CI | PG_V;
}
/*
! * Invalidate all but the final entry in the last kernel PT page
* (u-area PTEs will be validated later).
*/
pte = PA2VA(lkptpa, u_int *);
--- 318,324 ----
*pte = lkptpa | PG_RW | PG_CI | PG_V;
}
/*
! * Invalidate all entries in the last kernel PT page
* (u-area PTEs will be validated later).
*/
pte = PA2VA(lkptpa, u_int *);
***************
*** 445,450 ****
--- 446,460 ----
/*
* VM data structures are now initialized, set up data for
* the pmap module.
+ *
+ * Note about avail_end: msgbuf is initialized just after
+ * avail_end in machdep.c. Since the last page is used
+ * for rebooting the system (code is copied there and
+ * excution continues from copied code before the MMU
+ * is disabled), the msgbuf will get trounced between
+ * reboots if it's placed in the last physical page.
+ * To work around this, we move avail_end back one more
+ * page so the msgbuf can be preserved.
*/
avail_next = avail_start = m68k_round_page(nextpa);
avail_remaining = 0;
***************
*** 459,466 ****
}
physmem = m68k_btop(avail_remaining + nextpa - firstpa);
! avail_remaining -= m68k_round_page(MSGBUFSIZE);
! high[numranges - 1] -= m68k_round_page(MSGBUFSIZE);
avail_end = high[numranges - 1];
avail_remaining = m68k_btop(m68k_trunc_page(avail_remaining));
--- 469,477 ----
}
physmem = m68k_btop(avail_remaining + nextpa - firstpa);
! maxaddr = high[numranges - 1] - m68k_ptob(1);
! high[numranges - 1] -= (m68k_round_page(MSGBUFSIZE) + m68k_ptob(1));
! avail_remaining -= (m68k_round_page(MSGBUFSIZE) + m68k_ptob(1));
avail_end = high[numranges - 1];
avail_remaining = m68k_btop(m68k_trunc_page(avail_remaining));