fixed driver_vec retrieval. Sholdn't crash anymore on FireTOS.

This commit is contained in:
Markus Fröschle
2014-09-29 22:26:25 +00:00
parent 0c33198fbc
commit 628ba49c83
5 changed files with 56 additions and 11 deletions

View File

@@ -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

View File

@@ -1,2 +1,3 @@
include include
/usr/m68k-elf/include /usr/m68k-elf/include
tos

View File

@@ -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 */

View File

@@ -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)

View File

@@ -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];