mirror of
https://github.com/kanjitalk755/macemu.git
synced 2024-09-03 21:29:03 +00:00
added sources for "sheep" driver and "sheep_net" network add-on
This commit is contained in:
parent
4162bfeffb
commit
4fa9af7465
@ -86,7 +86,7 @@ SYSTEM_INCLUDE_PATHS =
|
||||
# additional paths to look for local headers
|
||||
# thes use the form: #include "header"
|
||||
# source file directories are automatically included
|
||||
LOCAL_INCLUDE_PATHS = ../include
|
||||
LOCAL_INCLUDE_PATHS = ../include SheepDriver SheepNet
|
||||
|
||||
# specify the level of optimization that you desire
|
||||
# NONE, SOME, FULL
|
||||
|
117
BasiliskII/src/BeOS/SheepDriver/Makefile
Normal file
117
BasiliskII/src/BeOS/SheepDriver/Makefile
Normal file
@ -0,0 +1,117 @@
|
||||
## BeOS Generic Makefile v2.1 ##
|
||||
|
||||
## Fill in this file to specify the project being created, and the referenced
|
||||
## makefile-engine will do all of the hard work for you. This handles both
|
||||
## Intel and PowerPC builds of the BeOS.
|
||||
|
||||
## Application Specific Settings ---------------------------------------------
|
||||
|
||||
# specify the name of the binary
|
||||
NAME= sheep
|
||||
|
||||
# specify the type of binary
|
||||
# APP: Application
|
||||
# SHARED: Shared library or add-on
|
||||
# STATIC: Static library archive
|
||||
# DRIVER: Kernel Driver
|
||||
TYPE= DRIVER
|
||||
|
||||
# add support for new Pe and Eddie features
|
||||
# to fill in generic makefile
|
||||
|
||||
#%{
|
||||
# @src->@
|
||||
|
||||
# specify the source files to use
|
||||
# full paths or paths relative to the makefile can be included
|
||||
# all files, regardless of directory, will have their object
|
||||
# files created in the common object directory.
|
||||
# Note that this means this makefile will not work correctly
|
||||
# if two source files with the same name (source.c or source.cpp)
|
||||
# are included from different directories. Also note that spaces
|
||||
# in folder names do not work well with this makefile.
|
||||
SRCS= sheep_driver.c
|
||||
|
||||
# specify the resource files to use
|
||||
# full path or a relative path to the resource file can be used.
|
||||
RSRCS=
|
||||
|
||||
# @<-src@
|
||||
#%}
|
||||
|
||||
# end support for Pe and Eddie
|
||||
|
||||
# specify additional libraries to link against
|
||||
# there are two acceptable forms of library specifications
|
||||
# - if your library follows the naming pattern of:
|
||||
# libXXX.so or libXXX.a you can simply specify XXX
|
||||
# library: libbe.so entry: be
|
||||
#
|
||||
# - if your library does not follow the standard library
|
||||
# naming scheme you need to specify the path to the library
|
||||
# and it's name
|
||||
# library: my_lib.a entry: my_lib.a or path/my_lib.a
|
||||
LIBS=
|
||||
|
||||
# specify additional paths to directories following the standard
|
||||
# libXXX.so or libXXX.a naming scheme. You can specify full paths
|
||||
# or paths relative to the makefile. The paths included may not
|
||||
# be recursive, so include all of the paths where libraries can
|
||||
# be found. Directories where source files are found are
|
||||
# automatically included.
|
||||
LIBPATHS=
|
||||
|
||||
# additional paths to look for system headers
|
||||
# thes use the form: #include <header>
|
||||
# source file directories are NOT auto-included here
|
||||
SYSTEM_INCLUDE_PATHS =
|
||||
|
||||
# additional paths to look for local headers
|
||||
# thes use the form: #include "header"
|
||||
# source file directories are automatically included
|
||||
LOCAL_INCLUDE_PATHS =
|
||||
|
||||
# specify the level of optimization that you desire
|
||||
# NONE, SOME, FULL
|
||||
OPTIMIZE= FULL
|
||||
|
||||
# specify any preprocessor symbols to be defined. The symbols will not
|
||||
# have their values set automatically; you must supply the value (if any)
|
||||
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
|
||||
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
|
||||
# would pass "-DDEBUG" on the compiler's command line.
|
||||
DEFINES=
|
||||
|
||||
# specify special warning levels
|
||||
# if unspecified default warnings will be used
|
||||
# NONE = supress all warnings
|
||||
# ALL = enable all warnings
|
||||
WARNINGS =
|
||||
|
||||
# specify whether image symbols will be created
|
||||
# so that stack crawls in the debugger are meaningful
|
||||
# if TRUE symbols will be created
|
||||
SYMBOLS =
|
||||
|
||||
# specify debug settings
|
||||
# if TRUE will allow application to be run from a source-level
|
||||
# debugger. Note that this will disable all optimzation.
|
||||
DEBUGGER =
|
||||
|
||||
# specify additional compiler flags for all files
|
||||
COMPILER_FLAGS =
|
||||
|
||||
# specify additional linker flags
|
||||
LINKER_FLAGS =
|
||||
|
||||
|
||||
## include the makefile-engine
|
||||
include /boot/develop/etc/makefile-engine
|
||||
|
||||
install: $(TARGET)
|
||||
cp $(TARGET) /boot/home/config/add-ons/kernel/drivers/bin
|
||||
ln -s /boot/home/config/add-ons/kernel/drivers/bin/$(NAME) /boot/home/config/add-ons/kernel/drivers/dev/$(NAME)
|
||||
|
||||
uninstall:
|
||||
rm /boot/home/config/add-ons/kernel/drivers/bin/$(NAME)
|
||||
rm /boot/home/config/add-ons/kernel/drivers/dev/$(NAME)
|
472
BasiliskII/src/BeOS/SheepDriver/sheep_driver.c
Normal file
472
BasiliskII/src/BeOS/SheepDriver/sheep_driver.c
Normal file
@ -0,0 +1,472 @@
|
||||
/*
|
||||
* sheep_driver.c - Low memory and ROM access driver for SheepShaver and
|
||||
* Basilisk II on PowerPC systems
|
||||
*
|
||||
* SheepShaver (C) 1997-2000 Mar"c Hellwig and Christian Bauer
|
||||
* Basilisk II (C) 1997-2000 Christian Bauer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <drivers/KernelExport.h>
|
||||
#include <drivers/Drivers.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "sheep_driver.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG==1
|
||||
#define bug pprintf
|
||||
#elif DEBUG==2
|
||||
#define bug dprintf
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
#define D(x) (x)
|
||||
#else
|
||||
#define D(x) ;
|
||||
#endif
|
||||
|
||||
#define PORT_NAME "sheep_driver installed"
|
||||
|
||||
|
||||
/*
|
||||
* For debugging
|
||||
*/
|
||||
|
||||
static int pprintf(const char* format, ...)
|
||||
{
|
||||
port_id PortNum;
|
||||
int len, ret;
|
||||
char Buffer[1024];
|
||||
va_list ap;
|
||||
|
||||
if ((PortNum = find_port("PortLogger")) == B_NAME_NOT_FOUND)
|
||||
return(PortNum);
|
||||
for (len=0; len<1024; len++)
|
||||
Buffer[len]='\0';
|
||||
va_start(ap, format);
|
||||
vsprintf(Buffer, format, ap);
|
||||
ret = write_port(PortNum, 0, Buffer, strlen(Buffer));
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Page table functions
|
||||
*/
|
||||
|
||||
static uint32 *pte_address = 0;
|
||||
static uint32 vsid;
|
||||
static uint32 table_size;
|
||||
|
||||
static status_t map_page(uint32 ea, uint32 ra, uint32 **free_pte, uint32 bits)
|
||||
{
|
||||
int i;
|
||||
int pte_class;
|
||||
uint32 hash1, hash2, api, *pteg1, *pteg2;
|
||||
|
||||
D(bug("Trying to map EA %p -> RA %p\n", ea, ra));
|
||||
|
||||
// Find PTEG addresses for given EA
|
||||
hash1 = (vsid & 0x7ffff) ^ ((ea >> 12) & 0xffff);
|
||||
hash2 = ~hash1 & 0x7ffff;
|
||||
api = (ea >> 22) & 0x3f;
|
||||
pteg1 = (uint32 *)((uint32)pte_address + ((hash1 << 6) & (table_size - 1)));
|
||||
pteg2 = (uint32 *)((uint32)pte_address + ((hash2 << 6) & (table_size - 1)));
|
||||
D(bug("PTEG1 at %p, PTEG2 at %p\n", pteg1, pteg2));
|
||||
|
||||
// Search all 8 PTEs of each PTEG
|
||||
*free_pte = NULL;
|
||||
pte_class = 0;
|
||||
for (i=0; i<8; i++) {
|
||||
D(bug(" found %08lx %08lx\n", pteg1[i*2], pteg1[i*2+1]));
|
||||
if (pteg1[i*2] == (0x80000000 | (vsid << 7) | (pte_class << 6) | api)) {
|
||||
*free_pte = pteg1 + i*2;
|
||||
D(bug(" existing PTE found (PTEG1)\n"));
|
||||
break;
|
||||
} else if (!pteg1[i*2]) {
|
||||
*free_pte = pteg1 + i*2;
|
||||
D(bug(" free PTE found (PTEG1)\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (*free_pte == NULL) {
|
||||
pte_class = 1;
|
||||
for (i=0; i<8; i++) {
|
||||
D(bug(" found %08lx %08lx\n", pteg2[i*2], pteg2[i*2+1]));
|
||||
if (pteg2[i*2] == (0x80000000 | (vsid << 7) | (pte_class << 6) | api)) {
|
||||
*free_pte = pteg2 + i*2;
|
||||
D(bug(" existing PTE found (PTEG2)\n"));
|
||||
break;
|
||||
} else if (!pteg2[i*2]) {
|
||||
*free_pte = pteg2 + i*2;
|
||||
D(bug(" free PTE found (PTEG2)\n"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remap page
|
||||
if (*free_pte == NULL) {
|
||||
D(bug(" No free PTE found :-(\m"));
|
||||
return B_DEVICE_FULL;
|
||||
} else {
|
||||
(*free_pte)[0] = 0x80000000 | (vsid << 7) | (pte_class << 6) | api;
|
||||
(*free_pte)[1] = ra | bits;
|
||||
D(bug(" written %08lx %08lx to PTE\n", (*free_pte)[0], (*free_pte)[1]));
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static status_t remap_page(uint32 *free_pte, uint32 ra, uint32 bits)
|
||||
{
|
||||
D(bug("Remapping PTE %p -> RA %p\n", free_pte, ra));
|
||||
|
||||
// Remap page
|
||||
if (free_pte == NULL) {
|
||||
D(bug(" Invalid PTE :-(\n"));
|
||||
return B_BAD_ADDRESS;
|
||||
} else {
|
||||
free_pte[1] = ra | bits;
|
||||
D(bug(" written %08lx %08lx to PTE\n", free_pte[0], free_pte[1]));
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Foward declarations for hook functions
|
||||
*/
|
||||
|
||||
static status_t sheep_open(const char *name, uint32 flags, void **cookie);
|
||||
static status_t sheep_close(void *cookie);
|
||||
static status_t sheep_free(void *cookie);
|
||||
static status_t sheep_control(void *cookie, uint32 op, void *data, size_t len);
|
||||
static status_t sheep_read(void *cookie, off_t pos, void *data, size_t *len);
|
||||
static status_t sheep_write(void *cookie, off_t pos, const void *data, size_t *len);
|
||||
|
||||
|
||||
/*
|
||||
* Version of our driver
|
||||
*/
|
||||
|
||||
int32 api_version = B_CUR_DRIVER_API_VERSION;
|
||||
|
||||
|
||||
/*
|
||||
* Device_hooks structure - has function pointers to the
|
||||
* various entry points for device operations
|
||||
*/
|
||||
|
||||
static device_hooks my_device_hooks = {
|
||||
&sheep_open,
|
||||
&sheep_close,
|
||||
&sheep_free,
|
||||
&sheep_control,
|
||||
&sheep_read,
|
||||
&sheep_write,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* List of device names to be returned by publish_devices()
|
||||
*/
|
||||
|
||||
static char *device_name_list[] = {
|
||||
"sheep",
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Init - do nothing
|
||||
*/
|
||||
|
||||
status_t init_hardware(void)
|
||||
{
|
||||
#if DEBUG==2
|
||||
set_dprintf_enabled(true);
|
||||
#endif
|
||||
D(bug("init_hardware()\n"));
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
status_t init_driver(void)
|
||||
{
|
||||
D(bug("init_driver()\n"));
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
void uninit_driver(void)
|
||||
{
|
||||
D(bug("uninit_driver()\n"));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* publish_devices - return list of device names implemented by this driver
|
||||
*/
|
||||
|
||||
const char **publish_devices(void)
|
||||
{
|
||||
return device_name_list;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* find_device - return device hooks for a specific device name
|
||||
*/
|
||||
|
||||
device_hooks *find_device(const char *name)
|
||||
{
|
||||
if (!strcmp(name, device_name_list[0]))
|
||||
return &my_device_hooks;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sheep_open - hook function for the open call.
|
||||
*/
|
||||
|
||||
static status_t sheep_open(const char *name, uint32 flags, void **cookie)
|
||||
{
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sheep_close - hook function for the close call.
|
||||
*/
|
||||
|
||||
static status_t sheep_close(void *cookie)
|
||||
{
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sheep_free - hook function to free the cookie returned
|
||||
* by the open hook. Since the open hook did not return
|
||||
* a cookie, this is a no-op.
|
||||
*/
|
||||
|
||||
static status_t sheep_free(void *cookie)
|
||||
{
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sheep_control - hook function for the ioctl call
|
||||
*/
|
||||
|
||||
static asm void inval_tlb(uint32 ea)
|
||||
{
|
||||
isync
|
||||
tlbie r3
|
||||
sync
|
||||
blr
|
||||
}
|
||||
|
||||
static asm void tlbsync(void)
|
||||
{
|
||||
machine 604
|
||||
tlbsync
|
||||
sync
|
||||
blr
|
||||
}
|
||||
|
||||
static status_t sheep_control(void *cookie, uint32 op, void *data, size_t len)
|
||||
{
|
||||
static void *block;
|
||||
static void *block_aligned;
|
||||
physical_entry pe[2];
|
||||
system_info sysinfo;
|
||||
area_id id;
|
||||
area_info info;
|
||||
cpu_status cpu_st;
|
||||
status_t res;
|
||||
uint32 ra0, ra1;
|
||||
uint32 *free_pte_0, *free_pte_1;
|
||||
int i;
|
||||
|
||||
D(bug("control(%d) data %p, len %08x\n", op, data, len));
|
||||
|
||||
switch (op) {
|
||||
case SHEEP_UP:
|
||||
|
||||
// Already messed up? Then do nothing now
|
||||
if (find_port(PORT_NAME) != B_NAME_NOT_FOUND)
|
||||
return B_NO_ERROR;
|
||||
|
||||
// Get system info
|
||||
get_system_info(&sysinfo);
|
||||
|
||||
// Prepare replacement memory
|
||||
block = malloc(B_PAGE_SIZE * 3);
|
||||
D(bug("3 pages malloc()ed at %p\n", block));
|
||||
block_aligned = (void *)(((uint32)block + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE-1));
|
||||
D(bug("Address aligned to %p\n", block_aligned));
|
||||
res = lock_memory(block_aligned, B_PAGE_SIZE * 2, 0);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
// Get memory mapping
|
||||
D(bug("Memory locked\n"));
|
||||
res = get_memory_map(block_aligned, B_PAGE_SIZE * 2, pe, 2);
|
||||
D(bug("get_memory_map returned %d\n", res));
|
||||
if (res != B_NO_ERROR)
|
||||
return res;
|
||||
|
||||
// Find PTE table area
|
||||
id = find_area("pte_table");
|
||||
get_area_info(id, &info);
|
||||
pte_address = (uint32 *)info.address;
|
||||
D(bug("PTE table seems to be at %p\n", pte_address));
|
||||
table_size = info.size;
|
||||
D(bug("PTE table size: %dKB\n", table_size / 1024));
|
||||
|
||||
// Disable interrupts
|
||||
cpu_st = disable_interrupts();
|
||||
|
||||
// Find vsid and real addresses of replacement memory
|
||||
for (i=0; i<table_size/8; i++) {
|
||||
if (((uint32)pe[0].address & 0xfffff000)==(pte_address[i*2+1]&0xfffff000)) {
|
||||
D(bug("Found page 0 PtePos %04x V%x VSID %03x H%x API %02x RPN %03x R%1x C%1x WIMG%1x PP%1x \n",
|
||||
i << 2,
|
||||
((pte_address[i*2]&0x80000000) >> 31),((pte_address[i*2]&0x7fffff80) >> 7),
|
||||
((pte_address[i*2]&0x00000040) >> 6),(pte_address[i*2] & 0x3f),
|
||||
((pte_address[i*2+1]&0xfffff000) >> 12),((pte_address[i*2+1]&0x00000100) >> 8),
|
||||
((pte_address[i*2+1]&0x00000080) >> 7),((pte_address[i*2+1]&0x00000078) >> 3),
|
||||
(pte_address[i*2+1]&0x00000003)));
|
||||
vsid = (pte_address[i*2]&0x7fffff80) >> 7;
|
||||
ra0 = (uint32)pe[0].address & 0xfffff000;
|
||||
}
|
||||
if ((uint32)pe[0].size == B_PAGE_SIZE) {
|
||||
if (((uint32)pe[1].address & 0xfffff000)==(pte_address[i*2+1]&0xfffff000)) {
|
||||
D(bug("Found page 1f PtePos %04x V%x VSID %03x H%x API %02x RPN %03x R%1x C%1x WIMG%1x PP%1x \n",
|
||||
i << 2,
|
||||
((pte_address[i*2]&0x80000000) >> 31), ((pte_address[i*2]&0x7fffff80) >> 7),
|
||||
((pte_address[i*2]&0x00000040) >> 6), (pte_address[i*2] & 0x3f),
|
||||
((pte_address[i*2+1]&0xfffff000) >> 12), ((pte_address[i*2+1]&0x00000100) >> 8),
|
||||
((pte_address[i*2+1]&0x00000080) >> 7), ((pte_address[i*2+1]&0x00000078) >> 3),
|
||||
(pte_address[i*2+1]&0x00000003)));
|
||||
ra1 = (uint32)pe[1].address & 0xfffff000;
|
||||
}
|
||||
} else {
|
||||
if ((((uint32)pe[0].address + B_PAGE_SIZE) & 0xfffff000)==(pte_address[i*2+1]&0xfffff000)) {
|
||||
D(bug("Found page 1d PtePos %04x V%x VSID %03x H%x API %02x RPN %03x R%1x C%1x WIMG%1x PP%1x \n",
|
||||
i << 2,
|
||||
((pte_address[i*2]&0x80000000) >> 31), ((pte_address[i*2]&0x7fffff80) >> 7),
|
||||
((pte_address[i*2]&0x00000040) >> 6), (pte_address[i*2] & 0x3f),
|
||||
((pte_address[i*2+1]&0xfffff000) >> 12), ((pte_address[i*2+1]&0x00000100) >> 8),
|
||||
((pte_address[i*2+1]&0x00000080) >> 7), ((pte_address[i*2+1]&0x00000078) >> 3),
|
||||
(pte_address[i*2+1]&0x00000003)));
|
||||
ra1 = ((uint32)pe[0].address + B_PAGE_SIZE) & 0xfffff000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Map low memory for emulator
|
||||
free_pte_0 = NULL;
|
||||
free_pte_1 = NULL;
|
||||
__sync();
|
||||
__isync();
|
||||
inval_tlb(0);
|
||||
inval_tlb(B_PAGE_SIZE);
|
||||
if (sysinfo.cpu_type != B_CPU_PPC_603 && sysinfo.cpu_type != B_CPU_PPC_603e)
|
||||
tlbsync();
|
||||
res = map_page(0, ra0, &free_pte_0, 0x12);
|
||||
if (res == B_NO_ERROR)
|
||||
res = map_page(B_PAGE_SIZE, ra1, &free_pte_1, 0x12);
|
||||
inval_tlb(0);
|
||||
inval_tlb(B_PAGE_SIZE);
|
||||
if (sysinfo.cpu_type != B_CPU_PPC_603 && sysinfo.cpu_type != B_CPU_PPC_603e)
|
||||
tlbsync();
|
||||
__sync();
|
||||
__isync();
|
||||
|
||||
// Restore interrupts
|
||||
restore_interrupts(cpu_st);
|
||||
|
||||
// Create port so we know that messing was successful
|
||||
set_port_owner(create_port(1, PORT_NAME), B_SYSTEM_TEAM);
|
||||
return B_NO_ERROR;
|
||||
|
||||
case SHEEP_DOWN:
|
||||
return B_NO_ERROR;
|
||||
|
||||
default:
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sheep_read - hook function for the read call
|
||||
*/
|
||||
|
||||
static status_t sheep_read(void *cookie, off_t pos, void *data, size_t *len)
|
||||
{
|
||||
void *rom_adr;
|
||||
area_id area;
|
||||
system_info info;
|
||||
|
||||
D(bug("read() pos %Lx, data %p, len %08x\n", pos, data, *len));
|
||||
|
||||
get_system_info(&info);
|
||||
if (info.platform_type == B_BEBOX_PLATFORM) {
|
||||
*len = 0;
|
||||
return B_ERROR;
|
||||
}
|
||||
if (*len != 0x400000 && pos != 0) {
|
||||
*len = 0;
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
area = map_physical_memory("mac_rom", (void *)0xff000000, 0x00400000, B_ANY_KERNEL_ADDRESS, B_READ_AREA, &rom_adr);
|
||||
D(bug("Mapped ROM to %p, area id %d\n", rom_adr, area));
|
||||
if (area < 0) {
|
||||
*len = 0;
|
||||
return area;
|
||||
}
|
||||
D(bug("Copying ROM\n"));
|
||||
memcpy(data, rom_adr, *len);
|
||||
D(bug("Deleting area\n"));
|
||||
delete_area(area);
|
||||
return B_NO_ERROR;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* sheep_write - hook function for the write call
|
||||
*/
|
||||
|
||||
static status_t sheep_write(void *cookie, off_t pos, const void *data, size_t *len)
|
||||
{
|
||||
D(bug("write() pos %Lx, data %p, len %08x\n", pos, data, *len));
|
||||
return B_READ_ONLY_DEVICE;
|
||||
}
|
33
BasiliskII/src/BeOS/SheepDriver/sheep_driver.h
Normal file
33
BasiliskII/src/BeOS/SheepDriver/sheep_driver.h
Normal file
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* sheep_driver.h - Low memory and ROM access driver for SheepShaver and
|
||||
* Basilisk II on PowerPC systems
|
||||
*
|
||||
* SheepShaver (C) 1997-2000 Mar"c" Hellwig and Christian Bauer
|
||||
* Basilisk II (C) 1997-2000 Christian Bauer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef SHEEP_DRIVER_H
|
||||
#define SHEEP_DRIVER_H
|
||||
|
||||
#include <drivers/Drivers.h>
|
||||
|
||||
enum {
|
||||
SHEEP_UP = B_DEVICE_OP_CODES_END + 1,
|
||||
SHEEP_DOWN
|
||||
};
|
||||
|
||||
#endif
|
115
BasiliskII/src/BeOS/SheepNet/Makefile
Normal file
115
BasiliskII/src/BeOS/SheepNet/Makefile
Normal file
@ -0,0 +1,115 @@
|
||||
## BeOS Generic Makefile v2.1 ##
|
||||
|
||||
## Fill in this file to specify the project being created, and the referenced
|
||||
## makefile-engine will do all of the hard work for you. This handles both
|
||||
## Intel and PowerPC builds of the BeOS.
|
||||
|
||||
## Application Specific Settings ---------------------------------------------
|
||||
|
||||
# specify the name of the binary
|
||||
NAME= sheep_net
|
||||
|
||||
# specify the type of binary
|
||||
# APP: Application
|
||||
# SHARED: Shared library or add-on
|
||||
# STATIC: Static library archive
|
||||
# DRIVER: Kernel Driver
|
||||
TYPE= SHARED
|
||||
|
||||
# add support for new Pe and Eddie features
|
||||
# to fill in generic makefile
|
||||
|
||||
#%{
|
||||
# @src->@
|
||||
|
||||
# specify the source files to use
|
||||
# full paths or paths relative to the makefile can be included
|
||||
# all files, regardless of directory, will have their object
|
||||
# files created in the common object directory.
|
||||
# Note that this means this makefile will not work correctly
|
||||
# if two source files with the same name (source.c or source.cpp)
|
||||
# are included from different directories. Also note that spaces
|
||||
# in folder names do not work well with this makefile.
|
||||
SRCS= sheep_net.cpp
|
||||
|
||||
# specify the resource files to use
|
||||
# full path or a relative path to the resource file can be used.
|
||||
RSRCS=
|
||||
|
||||
# @<-src@
|
||||
#%}
|
||||
|
||||
# end support for Pe and Eddie
|
||||
|
||||
# specify additional libraries to link against
|
||||
# there are two acceptable forms of library specifications
|
||||
# - if your library follows the naming pattern of:
|
||||
# libXXX.so or libXXX.a you can simply specify XXX
|
||||
# library: libbe.so entry: be
|
||||
#
|
||||
# - if your library does not follow the standard library
|
||||
# naming scheme you need to specify the path to the library
|
||||
# and it's name
|
||||
# library: my_lib.a entry: my_lib.a or path/my_lib.a
|
||||
LIBS= netdev
|
||||
|
||||
# specify additional paths to directories following the standard
|
||||
# libXXX.so or libXXX.a naming scheme. You can specify full paths
|
||||
# or paths relative to the makefile. The paths included may not
|
||||
# be recursive, so include all of the paths where libraries can
|
||||
# be found. Directories where source files are found are
|
||||
# automatically included.
|
||||
LIBPATHS=
|
||||
|
||||
# additional paths to look for system headers
|
||||
# thes use the form: #include <header>
|
||||
# source file directories are NOT auto-included here
|
||||
SYSTEM_INCLUDE_PATHS =
|
||||
|
||||
# additional paths to look for local headers
|
||||
# thes use the form: #include "header"
|
||||
# source file directories are automatically included
|
||||
LOCAL_INCLUDE_PATHS =
|
||||
|
||||
# specify the level of optimization that you desire
|
||||
# NONE, SOME, FULL
|
||||
OPTIMIZE= FULL
|
||||
|
||||
# specify any preprocessor symbols to be defined. The symbols will not
|
||||
# have their values set automatically; you must supply the value (if any)
|
||||
# to use. For example, setting DEFINES to "DEBUG=1" will cause the
|
||||
# compiler option "-DDEBUG=1" to be used. Setting DEFINES to "DEBUG"
|
||||
# would pass "-DDEBUG" on the compiler's command line.
|
||||
DEFINES=
|
||||
|
||||
# specify special warning levels
|
||||
# if unspecified default warnings will be used
|
||||
# NONE = supress all warnings
|
||||
# ALL = enable all warnings
|
||||
WARNINGS =
|
||||
|
||||
# specify whether image symbols will be created
|
||||
# so that stack crawls in the debugger are meaningful
|
||||
# if TRUE symbols will be created
|
||||
SYMBOLS =
|
||||
|
||||
# specify debug settings
|
||||
# if TRUE will allow application to be run from a source-level
|
||||
# debugger. Note that this will disable all optimzation.
|
||||
DEBUGGER =
|
||||
|
||||
# specify additional compiler flags for all files
|
||||
COMPILER_FLAGS =
|
||||
|
||||
# specify additional linker flags
|
||||
LINKER_FLAGS =
|
||||
|
||||
|
||||
## include the makefile-engine
|
||||
include /boot/develop/etc/makefile-engine
|
||||
|
||||
install: $(TARGET)
|
||||
cp $(TARGET) /boot/beos/system/add-ons/net_server/$(NAME)
|
||||
|
||||
uninstall:
|
||||
rm /boot/beos/system/add-ons/net_server/$(NAME)
|
294
BasiliskII/src/BeOS/SheepNet/sheep_net.cpp
Normal file
294
BasiliskII/src/BeOS/SheepNet/sheep_net.cpp
Normal file
@ -0,0 +1,294 @@
|
||||
/*
|
||||
* sheep_net.cpp - Net server add-on for SheepShaver and Basilisk II
|
||||
*
|
||||
* SheepShaver (C) 1997-2000 Mar"c" Hellwig and Christian Bauer
|
||||
* Basilisk II (C) 1997-2000 Christian Bauer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include <KernelKit.h>
|
||||
#include <SupportKit.h>
|
||||
#include <add-ons/net_server/NetDevice.h>
|
||||
#include <add-ons/net_server/NetProtocol.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "sheep_net.h"
|
||||
|
||||
#define DEBUG 0
|
||||
|
||||
#if DEBUG==1
|
||||
#define bug pprintf
|
||||
#elif DEBUG==2
|
||||
#define bug kprintf
|
||||
#endif
|
||||
|
||||
#if DEBUG
|
||||
#define D(x) (x)
|
||||
#else
|
||||
#define D(x) ;
|
||||
#endif
|
||||
|
||||
static int pprintf(const char* format, ...)
|
||||
{
|
||||
port_id PortNum;
|
||||
int len,Ret;
|
||||
char Buffer[1024];
|
||||
va_list ap;
|
||||
|
||||
if ((PortNum = find_port("PortLogger")) == B_NAME_NOT_FOUND)
|
||||
return(PortNum);
|
||||
for (len=0; len<1024; len++)
|
||||
Buffer[len]='\0';
|
||||
va_start(ap, format);
|
||||
vsprintf(Buffer, format, ap);
|
||||
Ret = write_port(PortNum, 0, Buffer, strlen(Buffer));
|
||||
return(Ret);
|
||||
}
|
||||
|
||||
|
||||
// Constants
|
||||
#define NETDUMP_PRIO 1 // Default is 0
|
||||
|
||||
const uint32 buffer_size = (sizeof(net_buffer) / B_PAGE_SIZE + 1) * B_PAGE_SIZE;
|
||||
|
||||
|
||||
// SheepNet add-on object
|
||||
class SheepNetAddOn : public BNetProtocol, BPacketHandler {
|
||||
public:
|
||||
void AddDevice(BNetDevice *dev, const char *name);
|
||||
bool PacketReceived(BNetPacket *buf, BNetDevice *dev);
|
||||
};
|
||||
|
||||
|
||||
// Global variables
|
||||
static bool shutdown_now = false;
|
||||
static bool active = false;
|
||||
|
||||
static thread_id write_thread; // Packet writer
|
||||
static sem_id write_sem; // Semaphore to trigger packet writing
|
||||
static BNetDevice *EtherCard = NULL; // The Ethernet card we are attached to
|
||||
static area_id buffer_area; // Packet buffer area
|
||||
static net_buffer *net_buffer_ptr; // Pointer to packet buffer
|
||||
|
||||
static uint32 rd_pos; // Current read position in packet buffer
|
||||
static uint32 wr_pos; // Current write position in packet buffer
|
||||
|
||||
|
||||
/*
|
||||
* Clear packet buffer
|
||||
*/
|
||||
|
||||
static void clear(void)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<READ_PACKET_COUNT;i++) {
|
||||
net_buffer_ptr->read[i].cmd = 0;
|
||||
net_buffer_ptr->read[i].length = 0;
|
||||
net_buffer_ptr->read[i].card = 0;
|
||||
net_buffer_ptr->read[i].reserved = 0;
|
||||
}
|
||||
for (i=0;i<WRITE_PACKET_COUNT;i++) {
|
||||
net_buffer_ptr->write[i].cmd = 0;
|
||||
net_buffer_ptr->write[i].length = 0;
|
||||
net_buffer_ptr->write[i].card = 0;
|
||||
net_buffer_ptr->write[i].reserved = 0;
|
||||
}
|
||||
rd_pos = wr_pos = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Packet writer thread
|
||||
*/
|
||||
|
||||
static status_t write_packet_func(void *arg)
|
||||
{
|
||||
while (!shutdown_now) {
|
||||
|
||||
// Read and execute command
|
||||
net_packet *p = &net_buffer_ptr->write[wr_pos];
|
||||
while (p->cmd & IN_USE) {
|
||||
D(bug("wp: %d\n", wr_pos));
|
||||
switch (p->cmd >> 8) {
|
||||
|
||||
case ACTIVATE_SHEEP_NET:
|
||||
D(bug("activate sheep-net\n"));
|
||||
active = false;
|
||||
clear();
|
||||
active = true;
|
||||
goto next;
|
||||
|
||||
case DEACTIVATE_SHEEP_NET:
|
||||
D(bug("deactivate sheep-net\n"));
|
||||
active = false;
|
||||
clear();
|
||||
goto next;
|
||||
|
||||
case SHUTDOWN_SHEEP_NET:
|
||||
D(bug("shutdown sheep-net\n"));
|
||||
active = false;
|
||||
clear();
|
||||
shutdown_now = true;
|
||||
goto next;
|
||||
|
||||
case ADD_MULTICAST: {
|
||||
const char *data = (const char *)p->data;
|
||||
D(bug("add multicast %02x %02x %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3], data[4], data[5]));
|
||||
if (active) {
|
||||
status_t result;
|
||||
if ((result = EtherCard->AddMulticastAddress(data)) != B_OK) {
|
||||
// !! handle error !! error while creating multicast address
|
||||
D(bug("error while creating multicast address %d\n", result));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case REMOVE_MULTICAST: {
|
||||
const char *data = (const char *)p->data;
|
||||
D(bug("remove multicast %02x %02x %02x %02x %02x %02x\n", data[0], data[1], data[2], data[3], data[4], data[5]));
|
||||
if (active) {
|
||||
status_t result;
|
||||
if ((result = EtherCard->RemoveMulticastAddress(data)) != B_OK) {
|
||||
// !! handle error !! error while removing multicast address
|
||||
D(bug("error while removing multicast address %d\n", result));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SHEEP_PACKET: {
|
||||
uint32 length = p->length;
|
||||
// D(bug("sheep packet %d\n", length));
|
||||
if (active) {
|
||||
BStandardPacket *packet = new BStandardPacket(length);
|
||||
packet->Write(0, (const char *)p->data, length);
|
||||
EtherCard->SendPacket(packet);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
D(bug("error: unknown port packet type\n"));
|
||||
break;
|
||||
}
|
||||
p->cmd = 0; // Free packet
|
||||
wr_pos = (wr_pos + 1) % WRITE_PACKET_COUNT;
|
||||
p = &net_buffer_ptr->write[wr_pos];
|
||||
}
|
||||
|
||||
// Wait for next packet
|
||||
next: acquire_sem_etc(write_sem, 1, B_TIMEOUT, 25000);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Init the net add-on
|
||||
*/
|
||||
|
||||
static void init_addon()
|
||||
{
|
||||
int i;
|
||||
D(bug("init sheep-net\n"));
|
||||
|
||||
// Create packet buffer
|
||||
if ((buffer_area = create_area("packet buffer", &net_buffer_ptr, B_ANY_ADDRESS, buffer_size, B_FULL_LOCK, B_READ_AREA | B_WRITE_AREA)) < B_NO_ERROR) {
|
||||
D(bug("FATAL ERROR: can't create shared area\n"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Init packet buffer
|
||||
clear();
|
||||
EtherCard->Address((char *)net_buffer_ptr->ether_addr);
|
||||
net_buffer_ptr->read_sem = -1;
|
||||
net_buffer_ptr->read_ofs = (uint32)(net_buffer_ptr->read) - (uint32)net_buffer_ptr;
|
||||
net_buffer_ptr->read_packet_size = sizeof(net_packet);
|
||||
net_buffer_ptr->read_packet_count = READ_PACKET_COUNT;
|
||||
if ((write_sem = create_sem(0, "ether write")) < B_NO_ERROR) {
|
||||
D(bug("FATAL ERROR: can't create semaphore\n"));
|
||||
return;
|
||||
}
|
||||
net_buffer_ptr->write_sem = write_sem;
|
||||
net_buffer_ptr->write_ofs = (uint32)(net_buffer_ptr->write) - (uint32)net_buffer_ptr;
|
||||
net_buffer_ptr->write_packet_size = sizeof(net_packet);
|
||||
net_buffer_ptr->write_packet_count = WRITE_PACKET_COUNT;
|
||||
|
||||
// Start packet writer thread
|
||||
write_thread = spawn_thread(write_packet_func, "sheep_net ether write", B_URGENT_DISPLAY_PRIORITY, NULL);
|
||||
resume_thread(write_thread);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Add-on attached to Ethernet card
|
||||
*/
|
||||
|
||||
void SheepNetAddOn::AddDevice(BNetDevice *dev, const char *name)
|
||||
{
|
||||
if (dev->Type() != B_ETHER_NET_DEVICE)
|
||||
return;
|
||||
if (EtherCard != NULL) {
|
||||
// !! handle error !! support for multiple ethernet cards ...
|
||||
D(bug("error: SheepShaver doesn't support multiple Ethernetcards !\n"));
|
||||
return;
|
||||
}
|
||||
EtherCard = dev;
|
||||
init_addon();
|
||||
register_packet_handler(this, dev, NETDUMP_PRIO);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Ethernet packet received
|
||||
*/
|
||||
|
||||
bool SheepNetAddOn::PacketReceived(BNetPacket *pkt, BNetDevice *dev)
|
||||
{
|
||||
if (shutdown_now) {
|
||||
unregister_packet_handler(this, dev);
|
||||
return false;
|
||||
}
|
||||
// D(bug("read_packet_func %d\n", pkt->Size()));
|
||||
if (active) {
|
||||
D(bug("rp: %d\n", rd_pos));
|
||||
net_packet *p = &net_buffer_ptr->read[rd_pos];
|
||||
if (p->cmd & IN_USE) {
|
||||
D(bug("error: full read buffer ... lost packet\n"));
|
||||
} else {
|
||||
memcpy(p->data, pkt->Data(), pkt->Size());
|
||||
p->length = pkt->Size();
|
||||
p->cmd = IN_USE | (SHEEP_PACKET << 8);
|
||||
rd_pos = (rd_pos + 1) % READ_PACKET_COUNT;
|
||||
release_sem(net_buffer_ptr->read_sem);
|
||||
}
|
||||
}
|
||||
//D(bug("%02x %02x %02x %02x %02x %02x", (uchar) (pkt->Data())[0],(uchar) (pkt->Data())[1],(uchar) (pkt->Data())[2],(uchar) (pkt->Data())[3],(uchar) (pkt->Data())[4],(uchar) (pkt->Data())[5]));
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma export on
|
||||
extern "C" BNetProtocol *open_protocol(const char *device)
|
||||
{
|
||||
SheepNetAddOn *dev = new SheepNetAddOn;
|
||||
return dev;
|
||||
}
|
||||
#pragma export off
|
@ -1,8 +1,22 @@
|
||||
/*
|
||||
* sheep_net.h - SheepShaver net server add-on
|
||||
* sheep_net.h - Net server add-on for SheepShaver and Basilisk II
|
||||
*
|
||||
* SheepShaver (C) 1997-2000 Mar"c Hellwig and Christian Bauer
|
||||
* All rights reserved.
|
||||
* Basilisk II (C) 1997-2000 Christian Bauer
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#ifndef SHEEP_NET_H
|
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* sheep_driver.h - Driver for SheepShaver (low memory, ROM access)
|
||||
*
|
||||
* SheepShaver (C) 1997-2000 Mar"c" Hellwig and Christian Bauer
|
||||
* All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef SHEEP_DRIVER_H
|
||||
#define SHEEP_DRIVER_H
|
||||
|
||||
#include <drivers/Drivers.h>
|
||||
|
||||
enum {
|
||||
SHEEP_UP = B_DEVICE_OP_CODES_END + 1,
|
||||
SHEEP_DOWN
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user