diff --git a/Makefile b/Makefile index d500d4a..d502eed 100644 --- a/Makefile +++ b/Makefile @@ -106,6 +106,7 @@ CSRCS= \ fbmem.c \ fbmon.c \ fbmodedb.c \ + offscreen.c \ \ videl.c \ video.c \ diff --git a/bas.lk.in b/bas.lk.in index 5787b0c..1653ff9 100644 --- a/bas.lk.in +++ b/bas.lk.in @@ -84,6 +84,7 @@ SECTIONS OBJDIR/fbmem.o OBJDIR/fbmon.o OBJDIR/fbmodedb.o + OBJDIR/offscreen.o OBJDIR/biosemu.o diff --git a/include/fb.h b/include/fb.h index dc62f70..4989d40 100644 --- a/include/fb.h +++ b/include/fb.h @@ -475,7 +475,7 @@ extern void framebuffer_release(struct fb_info *info); /* offscreen.c */ extern long offscreen_free(struct fb_info *info, long addr); extern long offscreen_alloc(struct fb_info *info, long amount); -extern long offscren_reserved(void); +extern long offscren_reserved(struct fb_info *info); extern void offscreen_init(struct fb_info *info); /* fbmon.c */ diff --git a/radeon/radeon_base.c b/radeon/radeon_base.c index 50a625c..36f55ef 100644 --- a/radeon/radeon_base.c +++ b/radeon/radeon_base.c @@ -2147,7 +2147,7 @@ int32_t radeonfb_pci_register(int32_t handle, const struct pci_device_id *ent) /* Probe screen types */ dbg("radeonfb: radeonfb_pci_register: probe screen types, monitor_layout: 0x%x\r\n", monitor_layout); - radeon_probe_screens(rinfo, monitor_layout, (int)ignore_edid); + radeon_probe_screens(rinfo, monitor_layout, (int) ignore_edid); /* Build mode list, check out panel native model */ dbg("radeonfb: radeonfb_pci_register: build mode list\r\n"); diff --git a/video/offscreen.c b/video/offscreen.c new file mode 100644 index 0000000..87d1052 --- /dev/null +++ b/video/offscreen.c @@ -0,0 +1,302 @@ +/* + * offscreen.c + * + * based from Emutos / BDOS + * + * Copyright (c) 2001 Lineo, Inc. + * + * Authors: Karl T. Braun, Martin Doering, Laurent Vogel + * + * This file is distributed under the GPL, version 2 or at your + * option any later version. + */ + +#include +#include +#include +#include "fb.h" + +#ifndef FALSE +#define FALSE 0 +#endif +#ifndef TRUE +#define TRUE 1 +#endif + +#undef DEBUG + +/* MD - Memory Descriptor */ + +#define MD struct _md_ + +MD +{ + MD *m_link; + long m_start; + long m_length; + void *m_own; +}; + +/* MPB - Memory Partition Block */ + +#define MPB struct _mpb + +MPB +{ + MD *mp_mfl; + MD *mp_mal; + MD *mp_rover; +}; + +#define MAXMD 256 + +static MD tab_md[MAXMD]; +static MPB pmd; +static long wrap; + +static void *xmgetblk(void) +{ + int i; + for(i = 0; i < MAXMD; i++) + { + if(tab_md[i].m_own == NULL) + { + tab_md[i].m_own = (void*)1L; + return(&tab_md[i]); + } + } + return(NULL); +} + +static void xmfreblk(void *m) +{ + int i = (int)(((long)m - (long)tab_md) / sizeof(MD)); + if((i > 0) && (i < MAXMD)) + tab_md[i].m_own = NULL; +} + +static MD *ffit(long amount, MPB *mp) +{ + MD *p,*q,*p1; /* free list is composed of MD's */ + int maxflg; + long maxval; + if(amount != -1) + { +#if 1 + amount += (wrap - 1); + amount /= wrap; + amount *= wrap; /* screen line alignment */ +#else + amount += 15; /* 16 bytes alignment */ + amount &= 0xFFFFFFF0; +#endif + } + if((q = mp->mp_rover) == 0) /* get rotating pointer */ + return(0) ; + maxval = 0; + maxflg = ((amount == -1) ? TRUE : FALSE) ; + p = q->m_link; /* start with next MD */ + do /* search the list for an MD with enough space */ + { + if(p == NULL) + { + /* at end of list, wrap back to start */ + q = (MD *) &mp->mp_mfl; /* q => mfl field */ + p = q->m_link; /* p => 1st MD */ + } + if((!maxflg) && (p->m_length >= amount)) + { + /* big enough */ + if(p->m_length == amount) + q->m_link = p->m_link; /* take the whole thing */ + else + { + /* break it up - 1st allocate a new + MD to describe the remainder */ + p1 = xmgetblk(); + if(p1 == NULL) + return(NULL); + /* init new MD */ + p1->m_length = p->m_length - amount; + p1->m_start = p->m_start + amount; + p1->m_link = p->m_link; + p->m_length = amount; /* adjust allocated block */ + q->m_link = p1; + } + /* link allocate block into allocated list, + mark owner of block, & adjust rover */ + p->m_link = mp->mp_mal; + mp->mp_mal = p; + mp->mp_rover = (q == (MD *) &mp->mp_mfl ? q->m_link : q); + return(p); /* got some */ + } + else if(p->m_length > maxval) + maxval = p->m_length; + p = ( q=p )->m_link; + } + while(q != mp->mp_rover); + /* return either the max, or 0 (error) */ + if(maxflg) + { + maxval -= 15; /* 16 bytes alignment */ + if(maxval < 0) + maxval = 0; + else + maxval &= 0xFFFFFFF0; + } + return(maxflg ? (MD *) maxval : 0); +} + +static void freeit(MD *m, MPB *mp) +{ + MD *p, *q; + q = NULL; + for(p = mp->mp_mfl; p ; p = (q=p) -> m_link) + { + if(m->m_start <= p->m_start) + break; + } + m->m_link = p; + if(q) + q->m_link = m; + else + mp->mp_mfl = m; + if(!mp->mp_rover) + mp->mp_rover = m; + if(p) + { + if(m->m_start + m->m_length == p->m_start) + { /* join to higher neighbor */ + m->m_length += p->m_length; + m->m_link = p->m_link; + if(p == mp->mp_rover) + mp->mp_rover = m; + xmfreblk(p); + } + } + if(q) + { + if(q->m_start + q->m_length == m->m_start) + { /* join to lower neighbor */ + q->m_length += m->m_length; + q->m_link = m->m_link; + if(m == mp->mp_rover) + mp->mp_rover = q; + xmfreblk(m); + } + } +} + +long offscreen_free(struct fb_info *info, long addr) +{ + MD *p,**q; + MPB *mpb; +#ifdef DEBUG + char buf[10]; + Funcs_puts("radeon_offscreen_free(0x"); + Funcs_ltoa(buf, addr, 16); + Funcs_puts(buf); + Funcs_puts("\r\n"); +#endif + *vblsem = 0; + mpb = &pmd; + for(p = *(q = &mpb->mp_mal); p; p = *(q = &p->m_link)) + { + if(addr == p->m_start) + break; + } + if(!p) + { + *vblsem = 1; + return(EFAULT); + } + *q = p->m_link; + freeit(p,mpb); + *vblsem = 1; + return(0); +} + +long offscreen_alloc(struct fb_info *info, long amount) +{ + long ret; + MD *m; +#ifdef DEBUG + char buf[10]; + Funcs_puts("radeon_offscreen_alloc(0x"); + Funcs_ltoa(buf, amount, 16); + Funcs_puts(buf); + Funcs_puts(") = 0x"); +#endif + *vblsem = 0; + if(amount == -1L) + { + ret = (long)ffit(-1L,&pmd); + *vblsem = 1; + return(ret); + } + if(amount <= 0 ) + { + *vblsem = 1; + return(0); + } + if((amount & 1)) + amount++; + m = ffit(amount,&pmd); + if(m == NULL) + { +#ifdef DEBUG + Funcs_puts("0\r\n"); +#endif + *vblsem = 1; + return(0); + } +#ifdef DEBUG + Funcs_ltoa(buf, m->m_start, 16); + Funcs_puts(buf); + Funcs_puts("\r\n"); +#endif + ret = (long)m->m_start; + *vblsem = 1; + return(ret); +} + +long offscren_reserved(struct fb_info *info) +{ + return((long)info_fvdi->ram_base + (long) info->ram_size); +} + +void offscreen_init(struct fb_info *info) +{ +#ifdef DEBUG + char buf[10]; +#endif + long size_screen, max_offscreen_size; + wrap = (long)info->var.xres_virtual * (long)(info->var.bits_per_pixel / 8); + size_screen = (long)info->var.yres_virtual * wrap; + if(!size_screen) + size_screen = (long)info->screen_size; + pmd.mp_mfl = pmd.mp_rover = &tab_md[0]; + tab_md[0].m_link = (MD *)NULL; + tab_md[0].m_start = (long)((unsigned long)info->ram_base + (unsigned long)size_screen); + tab_md[0].m_length = (long)info->ram_size - size_screen; + tab_md[0].m_own = (void *)1L; + max_offscreen_size = ((long)info->var.xres_virtual * 8192L * (long)(info->var.bits_per_pixel / 8)) - size_screen; + if(max_offscreen_size < 0) + max_offscreen_size = 0; + if(tab_md[0].m_length > max_offscreen_size) + tab_md[0].m_length = max_offscreen_size; +#ifdef DEBUG + Funcs_puts("offscreen_init start 0x"); + Funcs_ltoa(buf, tab_md[0].m_start, 16); + Funcs_puts(buf); + Funcs_puts(", length 0x"); + Funcs_ltoa(buf, tab_md[0].m_length, 16); + Funcs_puts(buf); + Funcs_puts(", ram_size 0x"); + Funcs_ltoa(buf, (long)info->ram_size, 16); + Funcs_puts(buf); + Funcs_puts("\r\n"); +#endif + pmd.mp_mal = (MD *)NULL; +} + diff --git a/x86emu/biosemu.c b/x86emu/biosemu.c index 32310b4..091f3ac 100644 --- a/x86emu/biosemu.c +++ b/x86emu/biosemu.c @@ -3,6 +3,7 @@ #include "bas_printf.h" #include "bas_string.h" #include "util.h" +#include "driver_mem.h" #include "x86emu.h" #include "pci.h" #include "pci_ids.h" @@ -211,9 +212,7 @@ void outl(uint32_t val, uint16_t port) void do_int(int num) { int ret = 0; -// DPRINTVAL("int ", num); -// DPRINTVALHEX(" vector at ", getIntVect(num)); -// DPRINT("\r\n"); + switch (num) { #ifndef _PC @@ -221,7 +220,7 @@ void do_int(int num) case 0x42: case 0x6D: if (getIntVect(num) == 0x0000) - DPRINT("un-inited int vector\r\n"); + dbg("uninitialised int vector\r\n"); if (getIntVect(num) == 0xFF065) { //ret = int42_handler(); @@ -542,64 +541,55 @@ void run_bios(struct radeonfb_info *rinfo) X86EMU_intrFuncs intFuncs[256]; if ((rinfo->mmio_base == NULL) || (rinfo->io_base == NULL)) + { + dbg("%s: rinfo->mmio_base = %p, rinfo->io_base = %p\r\n", __FUNCTION__); return; + } rinfo_biosemu = rinfo; config_address_reg = 0; offset_port = 0x300; #ifdef DIRECT_ACCESS - offset_io = (uint32_t)rinfo->io_base-(uint32_t)offset_port; - offset_mem = (uint32_t)rinfo->fb_base-0xA0000; + offset_io = (uint32_t) rinfo->io_base - (uint32_t) offset_port; + offset_mem = (uint32_t) rinfo->fb_base - 0xA0000; #else - offset_io = rinfo->io_base_phys-(uint32_t)offset_port; - offset_mem = rinfo->fb_base_phys-0xA0000; + offset_io = rinfo->io_base_phys -(uint32_t) offset_port; + offset_mem = rinfo->fb_base_phys - 0xA0000; #endif - rom_header = (struct rom_header *)0; + rom_header = (struct rom_header *) 0; do { rom_header = (struct rom_header *)((unsigned long)rom_header + image_size); // get next image rom_data = (struct pci_data *)((unsigned long)rom_header + (unsigned long)BIOS_IN16((long)&rom_header->data)); image_size = (unsigned long)BIOS_IN16((long)&rom_data->ilen) * 512; - } - while((BIOS_IN8((long)&rom_data->type) != 0) && (BIOS_IN8((long)&rom_data->indicator) != 0)); // make sure we got x86 version - if (BIOS_IN8((long)&rom_data->type) != 0) - return; - rom_size = (unsigned long)BIOS_IN8((long)&rom_header->size) * 512; - if (PCI_CLASS_DISPLAY_VGA == BIOS_IN16((long)&rom_data->class_hi)) + } while ((BIOS_IN8((long) &rom_data->type) != 0) && (BIOS_IN8((long) &rom_data->indicator) != 0)); // make sure we got x86 version + if (BIOS_IN8((long) &rom_data->type) != 0) { -#ifdef USE_SDRAM -#if 0 - if (os_magic) - { - biosmem = Mxalloc(SIZE_EMU, 3); - if (biosmem == 0) - return; - } -#endif -#else - biosmem = Mxalloc(SIZE_EMU, 0); + dbg("%s: ROM data type = 0x%x\r\n", __FUNCTION__, BIOS_IN8((long) &rom_data->type)); + return; + } + rom_size = (unsigned long) BIOS_IN8((long) &rom_header->size) * 512; + if (PCI_CLASS_DISPLAY_VGA == BIOS_IN16((long) &rom_data->class_hi)) + { + biosmem = driver_mem_alloc(SIZE_EMU); if (biosmem == 0) - return; -#endif /* USE_SDRAM */ - memset((char *)biosmem, 0, SIZE_EMU); - setup_system_bios((char *)biosmem); - DPRINTVALHEX("Copying VGA ROM Image from ", (long)rinfo->bios_seg+(long)rom_header); - DPRINTVALHEX(" to ", biosmem+PCI_VGA_RAM_IMAGE_START); - DPRINTVALHEX(", ", rom_size); - DPRINT(" bytes\r\n"); -#if 0 // 8 bits copy - ptr = (char *)biosmem; - for(i = (long)rom_header, j = PCI_VGA_RAM_IMAGE_START; i < (long)rom_header+rom_size; ptr[j++] = BIOS_IN8(i++)); -#else // 32 bits copy { - long bytes_align = (long)rom_header & 3; - ptr = (unsigned char *)biosmem; - i = (long)rom_header; + dbg("%s: could not allocate X86 BIOS memory\r\n", __FUNCTION__); + return; + } + memset((char *) biosmem, 0, SIZE_EMU); + setup_system_bios((char *) biosmem); + dbg("Copying VGA ROM Image from %p to %p (0x%lx bytes)\r\n", (long) rinfo->bios_seg + (long) rom_header, + biosmem + PCI_VGA_RAM_IMAGE_START, rom_size); + { + long bytes_align = (long) rom_header & 3; + + ptr = (unsigned char *) biosmem; + i = (long) rom_header; j = PCI_VGA_RAM_IMAGE_START; if (bytes_align) for(; i < 4 - bytes_align; ptr[j++] = BIOS_IN8(i++)); - for(; i < (long)rom_header+rom_size; *((unsigned long *)&ptr[j]) = swpl(BIOS_IN32(i)), i+=4, j+=4); + for(; i < (long) rom_header + rom_size; *((unsigned long *)&ptr[j]) = swpl(BIOS_IN32(i)), i += 4, j += 4); } -#endif addr = PCI_VGA_RAM_IMAGE_START; } else @@ -620,34 +610,35 @@ void run_bios(struct radeonfb_info *rinfo) #endif /* USE_SDRAM */ setup_system_bios((char *)biosmem); memset((char *)biosmem, 0, SIZE_EMU); - DPRINTVALHEX("Copying non-VGA ROM Image from ", (long)rinfo->bios_seg+(long)rom_header); - DPRINTVALHEX(" to ", biosmem+PCI_RAM_IMAGE_START); - DPRINTVALHEX(", ", rom_size); - DPRINT(" bytes\r\n"); - ptr = (unsigned char *)biosmem; - for(i = (long)rom_header, j = PCI_RAM_IMAGE_START; i < (long)rom_header+rom_size; ptr[j++] = BIOS_IN8(i++)); + dbg("Copying non-VGA ROM Image from %p to %p (0x%lx bytes)\r\n", + (long) rinfo->bios_seg + (long) rom_header, + biosmem + PCI_RAM_IMAGE_START, + rom_size); + ptr = (unsigned char *) biosmem; + for (i = (long) rom_header, j = PCI_RAM_IMAGE_START; i < (long) rom_header+rom_size; ptr[j++] = BIOS_IN8(i++)); addr = PCI_RAM_IMAGE_START; } initialcs = (addr & 0xF0000) >> 4; initialip = (addr + 3) & 0xFFFF; - X86EMU_setMemBase((void *)biosmem, SIZE_EMU); - for(i = 0; i < 256; i++) + X86EMU_setMemBase((void *) biosmem, SIZE_EMU); + for (i = 0; i < 256; i++) intFuncs[i] = do_int; X86EMU_setupIntrFuncs(intFuncs); { char *date = "01/01/99"; - for(i = 0; date[i]; i++) + for (i = 0; date[i]; i++) wrb(0xffff5 + i, date[i]); wrb(0xffff7, '/'); wrb(0xffffa, '/'); } { - /* FixME: move PIT init to its own file */ - outb(0x36, 0x43); - outb(0x00, 0x40); - outb(0x00, 0x40); + /* FixME: move PIT init to its own file */ + outb(0x36, 0x43); + outb(0x00, 0x40); + outb(0x00, 0x40); } // setup_int_vect(); + /* cpu setup */ X86_AX = devfn ? devfn : 0xff; X86_DX = 0x80; @@ -658,6 +649,7 @@ void run_bios(struct radeonfb_info *rinfo) X86_SP = 0xfffe; X86_DS = 0x0040; X86_ES = 0x0000; + /* We need a sane way to return from bios * execution. A hlt instruction and a pointer * to it, both kept on the stack, will do. @@ -671,13 +663,13 @@ void run_bios(struct radeonfb_info *rinfo) pushw(X86_SP + 2); #ifdef DEBUG_X86EMU X86EMU_trace_on(); - X86EMU_set_debug(DEBUG_DECODE_F | DEBUG_TRACE_F); + X86EMU_set_debug(DEBUG_DECODE_F | DEBUG_TRACE_F); #endif - DPRINT("X86EMU entering emulator\r\n"); + dbg("X86EMU entering emulator\r\n"); //*vblsem = 0; X86EMU_exec(); //*vblsem = 1; - DPRINT("X86EMU halted\r\n"); + dbg("X86EMU halted\r\n"); // biosfn_set_video_mode(0x13); /* 320 x 200 x 256 colors */ #ifdef USE_SDRAM #if 0 @@ -688,7 +680,7 @@ void run_bios(struct radeonfb_info *rinfo) } #endif #else - memset((char *)biosmem, 0, SIZE_EMU); - Mfree(biosmem); + memset((char *) biosmem, 0, SIZE_EMU); + driver_mem_free(biosmem); #endif /* USE_SDRAM */ }