fixed driver_vec retrieval. Sholdn't crash anymore on FireTOS.
This commit is contained in:
@@ -269,3 +269,4 @@ tos/bascook/sources/bascook.c
|
|||||||
tos/Makefile
|
tos/Makefile
|
||||||
usb/usb_hub.c
|
usb/usb_hub.c
|
||||||
include/usb_hub.h
|
include/usb_hub.h
|
||||||
|
tos/Makefile
|
||||||
|
|||||||
@@ -1,2 +1,3 @@
|
|||||||
include
|
include
|
||||||
/usr/m68k-elf/include
|
/usr/m68k-elf/include
|
||||||
|
tos
|
||||||
|
|||||||
@@ -137,9 +137,9 @@ static struct framebuffer_driver_interface framebuffer_interface =
|
|||||||
*/
|
*/
|
||||||
static struct mmu_driver_interface mmu_interface =
|
static struct mmu_driver_interface mmu_interface =
|
||||||
{
|
{
|
||||||
.map_page_locked = &mmu_map_data_page_locked,
|
.map_page_locked = &mmu_map_data_page_locked,
|
||||||
.unlock_page = &mmu_unlock_data_page,
|
.unlock_page = &mmu_unlock_data_page,
|
||||||
.report_locked_pages = &mmu_report_locked_pages
|
.report_locked_pages = &mmu_report_locked_pages
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct generic_interface interfaces[] =
|
static struct generic_interface interfaces[] =
|
||||||
@@ -206,8 +206,28 @@ static struct driver_table bas_drivers =
|
|||||||
|
|
||||||
void __attribute__((interrupt)) get_bas_drivers(void)
|
void __attribute__((interrupt)) get_bas_drivers(void)
|
||||||
{
|
{
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile(
|
||||||
"move.l #%[drivers],d0\n\t"
|
/*
|
||||||
|
* sp should now point to the next instruction after the trap
|
||||||
|
* The trap itself is 2 bytes, the four bytes before that must
|
||||||
|
* read '_BAS' or we are not meant by this call
|
||||||
|
*/
|
||||||
|
" move.l d0,-(sp) \n\t" // save register
|
||||||
|
" move.l 10(sp),d0 \n\t" // get "magic word"
|
||||||
|
" cmp.l #0x5f424153,d0 \n\t" // is it '_BAS'?
|
||||||
|
" beq fetch_drivers \n\t" // yes
|
||||||
|
/*
|
||||||
|
* This seems indeed a "normal" trap #0. Better pass control to "normal" trap #0 processing
|
||||||
|
* If trap #0 isn't set to something sensible, we'll probably crash here, but this must be
|
||||||
|
* prevented on the caller side.
|
||||||
|
*/
|
||||||
|
" move.l (sp)+,d0 \n\t" // restore register
|
||||||
|
" move.l 0x80,-(sp) \n\t" // fetch vector
|
||||||
|
" rts \n\t" // and jump through it
|
||||||
|
|
||||||
|
"fetch_drivers: \n\t"
|
||||||
|
" move.l #%[drivers],d0 \n\t" // return driver struct in d0
|
||||||
|
" addq.l #4,sp \n\t" // adjust stack
|
||||||
: /* no output */
|
: /* no output */
|
||||||
: [drivers] "o" (bas_drivers) /* input */
|
: [drivers] "o" (bas_drivers) /* input */
|
||||||
: /* clobber */
|
: /* clobber */
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
.PHONY: tos
|
.PHONY: tos
|
||||||
.PHONY: jtagwait
|
.PHONY: jtagwait
|
||||||
.PHONY: mcdcook
|
.PHONY: bascook
|
||||||
tos: jtagwait mcdcook
|
tos: jtagwait bascook
|
||||||
|
|
||||||
jtagwait:
|
jtagwait:
|
||||||
(cd $@; make)
|
(cd $@; make)
|
||||||
|
|
||||||
bascook:
|
bascook:
|
||||||
(cd $@; make)
|
(cd $@; make)
|
||||||
|
|
||||||
|
|||||||
@@ -10,8 +10,10 @@ struct driver_table *get_bas_drivers(void)
|
|||||||
struct driver_table *ret = NULL;
|
struct driver_table *ret = NULL;
|
||||||
|
|
||||||
__asm__ __volatile__(
|
__asm__ __volatile__(
|
||||||
" trap #0\n\t"
|
" bra.s do_trap \n\t"
|
||||||
" move.l d0,%[ret]\n\t"
|
" .dc.l 0x5f424153 \n\t" // '_BAS'
|
||||||
|
"do_trap: trap #0 \n\t"
|
||||||
|
" move.l d0,%[ret] \n\t"
|
||||||
: [ret] "=m" (ret) /* output */
|
: [ret] "=m" (ret) /* output */
|
||||||
: /* no inputs */
|
: /* no inputs */
|
||||||
: /* clobbered */
|
: /* clobbered */
|
||||||
@@ -20,6 +22,22 @@ struct driver_table *get_bas_drivers(void)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* temporarily replace the trap 0 handler with this so we can avoid
|
||||||
|
* getting caught by BaS versions that don't understand the driver interface
|
||||||
|
* exposure call.
|
||||||
|
* If we get here, we have a BaS version that doesn't support the trap 0 interface
|
||||||
|
*/
|
||||||
|
static void __attribute__((interrupt)) my_own_trap0_handler(void)
|
||||||
|
{
|
||||||
|
__asm__ __volatile__(
|
||||||
|
" clr.l d0 \n\t" // return 0 to indicate not supported
|
||||||
|
:
|
||||||
|
:
|
||||||
|
:
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
static uint32_t cookieptr(void)
|
static uint32_t cookieptr(void)
|
||||||
{
|
{
|
||||||
return * (uint32_t *) 0x5a0L;
|
return * (uint32_t *) 0x5a0L;
|
||||||
@@ -86,11 +104,16 @@ int main(int argc, char *argv[])
|
|||||||
{
|
{
|
||||||
struct driver_table *dt;
|
struct driver_table *dt;
|
||||||
void *ssp;
|
void *ssp;
|
||||||
|
void *old_vector;
|
||||||
|
|
||||||
(void) Cconws("retrieve BaS driver interface\r\n");
|
(void) Cconws("retrieve BaS driver interface\r\n");
|
||||||
|
|
||||||
ssp = (void *) Super(0L);
|
ssp = (void *) Super(0L);
|
||||||
dt = get_bas_drivers();
|
|
||||||
|
old_vector = Setexc(0x20, my_own_trap0_handler); /* set our own temporarily */
|
||||||
|
dt = get_bas_drivers(); /* trap #1 */
|
||||||
|
(void) Setexc(0x20, old_vector); /* restore original vector */
|
||||||
|
|
||||||
if (dt)
|
if (dt)
|
||||||
{
|
{
|
||||||
struct generic_interface *ifc = &dt->interfaces[0];
|
struct generic_interface *ifc = &dt->interfaces[0];
|
||||||
|
|||||||
Reference in New Issue
Block a user