diff --git a/src/sys/drivers/pci_pio.c b/src/sys/drivers/pci_pio.c new file mode 100755 index 0000000..a5a527d --- /dev/null +++ b/src/sys/drivers/pci_pio.c @@ -0,0 +1,263 @@ +/* + * $Id$ + */ + +/* + * Copyright (c) 2002 Johnny Zackrisson. All rights reserved. + * + * You are free to do whatever you want with this code. + */ + +#include +#include + +#ifdef _PCI_SUPPORT_ + +/* + * Fill in your shit, recompile and prey. + */ +#define PCI_DEVS /* how many devices */ +struct pci_device_id_t pci_devices = { + /* Vendor id, device id, name */ + 0x0000,0x0000,"Oak Technologies" /* example */ +}; +#endif /* PCI_DEVS */ + +/* XXX: these does not belong here */ +static void outb(u16 port, u8 data); +static void outw(u16 port, u16 data); +static void outl(u16 port, u32 data); +static u8 inb(u16 port); +static u16 inw(u16 port); +static u32 inl(u16 port); + +/* + * XXX: static? + */ +int pci_get_type(); +int pci_init(); +int pci_find_devices(struct pci_conf_t *pci_conf[]); +int pci_t1_read_config(struct pci_conf_t *pci_conf, unsigned int dev); +int pci_t1_write_config(struct pci_conf_t *pci_conf, unsigned int dev); +int pci_t2_read_config(struct pci_conf_t *pci_conf, unsigned int dev); +int pci_t2_write_config(struct pci_conf_t *pci_conf, unsigned int dev); + +int +pci_init() +{ + + + return(0); +} + +int +pci_get_type() +{ + int x,t=0; + + outb(PCI_BASE, 0); + outb(PCI_INDEX_REG, 0); + + x = inb(PCI_BASE) + inb(PCI_INDEX_REG); + if (x == 0) + t = PCI_TYPE_2; + + x = inb(PCI_BASE); + outl(PCI_BASE, BUS_ADDRESS); + x = inl(PCI_BASE); + if (x == BUS_ADDRESS) + t = PCI_TYPE_1; + outl(PCI_BASE, x); + + return(t); +} + +int +pci_find_devices(struct pci_conf_t *pci_conf[]) +{ + int dev,i,x; + + x = pci_get_type(); + + if (x == PCI_TYPE_1) { + for (i=0; ivendor_id != 0xffff && + pci_conf[dev]->device_id != 0xffff) + dev++; + } + + return(0); + + } else if (x == PCI_TYPE_2) { + for (i=0; ivendor_id != 0xffff && + pci_conf[dev]->device_id != 0xffff) + dev++; + } + + return(0); + } + + return(-1); +} + +/* PCI type 1 access method */ + +int +pci_t1_read_config(struct pci_conf_t *pci_conf, unsigned int dev) +{ + unsigned int i; + + dev <<= 11; + for (i=0; i<64; i++) { + outl(PCI_BASE, (BUS_ADDRESS+(dev+(i*4)))); + ((u32 *)pci_conf)[i] = inl(PCI_T1_INDEX_REG); + } + + if ((pci_conf->vendor_id == 0xffff) && + (pci_conf->device_id == 0xffff)) + return(-1); + + return(0); +} + +int +pci_t1_write_config(struct pci_conf_t *pci_conf, unsigned int dev) +{ + int i; + + /* bit 0-7 index into the conf space */ + dev <<= 11; + for (i=0; i<64; i++) { + outl(PCI_BASE, (BUS_ADDRESS+(dev+(i*4)))); + outl(PCI_T1_INDEX_REG, ((u32 *)pci_conf)[i]); + } + + return(0); +} + +/* PCI type 2 access method */ + +int +pci_t2_read_config(struct pci_conf_t *pci_conf, unsigned int dev) +{ + int i,x; + + /* bit 7 set to select the PCI configuration space */ + x = (((dev & 7) << 1) | 0xf0); + outb(PCI_BASE, x); + + /* bus select? */ + outb(PCI_INDEX_REG, 0); + + for (i=0; i<64; i++) + ((u32 *)pci_conf)[i] = inl(V_BUS_ADDRESS+((dev<<8)+(i*4))); + + outb(PCI_BASE,0); + + return(0); +} + +int +pci_t2_write_config(struct pci_conf_t *pci_conf, unsigned int dev) +{ + int i,x; + + /* bit 7 set to select the PCI configuration space */ + x = (((dev & 7) << 1) | 0xf0); + outb(PCI_BASE, x); + + /* bus select? */ + outb(PCI_INDEX_REG, 0); + + for (i=0; i<64; i++) + outl(V_BUS_ADDRESS+((dev<<8)+(i*4)), ((u32 *)pci_conf)[i]); + + outb(PCI_BASE, 0); + + return(0); +} + + +/* XXX: these functions below should be in a nice library. */ +/* write data to port */ + +static void +outb(u16 port, u8 data) +{ + __asm__ __volatile__( + "outb %1,%0" + : + : "Nd" (port), + "a" (data) + ); +} + +static void +outw(u16 port, u16 data) +{ + __asm__ __volatile__( + "outw %1,%0" + : + : "Nd" (port), + "a" (data) + ); +} + +static void +outl(u16 port, u32 data) +{ + __asm__ __volatile__( + "outl %1,%0" + : + : "Nd" (port), + "a" (data) + ); +} + + +/* get data from port */ + +static u8 +inb(u16 port) +{ + u8 ret; + + __asm__ __volatile__( + "inb %1,%0" + : "=a" (ret) + : "Nd" (port) + ); + + return(port); +} + +static u16 +inw(u16 port) +{ + u16 ret; + + __asm__ __volatile__( + "inw %1,%0" + : "=a" (ret) + : "Nd" (port) + ); + + return(ret); +} + +static u32 +inl(u16 port) +{ + u32 ret; + + __asm__ __volatile__( + "inl %1,%0" + : "=a" (ret) + : "Nd" (port) + ); + + return(ret); +} diff --git a/src/sys/include/config.h b/src/sys/include/config.h new file mode 100755 index 0000000..44b2b29 --- /dev/null +++ b/src/sys/include/config.h @@ -0,0 +1,7 @@ +#ifndef _SYS_CONFIG_H_ +#define _SYS_CONFIG_H_ + + + + +#endif /* _SYS_CONFIG_H_ */ diff --git a/src/sys/include/drivers/pci_pio.h b/src/sys/include/drivers/pci_pio.h new file mode 100755 index 0000000..cf21789 --- /dev/null +++ b/src/sys/include/drivers/pci_pio.h @@ -0,0 +1,194 @@ +/* + * $Id$ + */ + +#ifndef _PCI_PIO_H_ +#define _PCI_PIO_H_ + +#define PCI_TYPE_1 1 +#define PCI_TYPE_2 2 +#define PCI_BUSSES 16 + +#define PCI_BASE 0xcf8 +#define PCI_INDEX_REG 0xcfa +#define PCI_T1_INDEX_REG 0xcfc + +#define BUS_ADDRESS 0x80000000 +#define V_BUS_ADDRESS 0xc000 + +int pci_get_type(void); +int pci_init(void); +int pci_find_devices(struct pci_conf_t *pci_conf[]); +int pci_t1_read_config(struct pci_conf_t *pci_conf, unsigned int dev); +int pci_t1_write_config(struct pci_conf_t *pci_conf, unsigned int dev); +int pci_t2_read_config(struct pci_conf_t *pci_conf, unsigned int dev); +int pci_t2_write_config(struct pci_conf_t *pci_conf, unsigned int dev); + +struct pci_device_id_t { + u16 vendor_id; + u16 device_id; + const u8 *name; +}; + +struct pci_conf_t { + u16 vendor_id; + u16 device_id; + struct command { + u16 response_io : 1, + response_memory : 1, + bus_master : 1, + special_cycles : 1, + invalidate : 1, + vga_pal_snoop : 1, + parity : 1, + wait_cc : 1, + system_error : 1, + back2back_c : 1, + fast_back_c : 1, + res : 6; + }; + struct status { + u16 res_low : 4, + capability_list : 1, + fast_bus : 1, /* 66MHz PCI bus */ + user_def_features : 1, + fast_back_c : 1, + parity : 1, + devsel_timing : 2, /* 0=fast, 1=medium, 2=slow */ + device_target_abort : 1, + recv_target_abort : 1, + master_abort_stat : 1, + signal_sys_err : 1, + detected_parity : 1; + }; + + u8 revision_code, + programming_interface; + u16 class; + u8 cache_line_size, + latency_timer, /* bit 0-2 res */ + header_type, + bist; /* ??? */ + u32 addr[2]; + u8 header; +}; + +struct pci_dev_conf_t{ + u32 addr[4], + cardbus_cis; + u16 subsystem_vendor_id, + subsystem_id; + u32 rom_address_enable : 1, + reserved : 10, + rom_address : 21; + u8 capability_list, + reserved2 : 6, + interrupt_line, + interrupt_pin, + minimum_granularity, + max_latency; +}; + +#define PCI_CAPABILITY_LIST_ID 0 + +/* Power Management. */ + +#define PCI_CAPABILITY_ID_PM 0x01 + +/* Accelerated Graphics Port. */ + +#define PCI_CAPABILITY_ID_AGP 0x02 + +/* Next capability in the list. */ + +#define PCI_CAP_LIST_NEXT 1 + +/* Device classes and subclasses. */ +#define PCI_CLASS_NOT_DEFINED 0x0000 +#define PCI_CLASS_NOT_DEFINED_VGA 0x0001 + +#define PCI_BASE_CLASS_STORAGE 0x01 +#define PCI_CLASS_STORAGE_SCSI 0x0100 +#define PCI_CLASS_STORAGE_IDE 0x0101 +#define PCI_CLASS_STORAGE_FLOPPY 0x0102 +#define PCI_CLASS_STORAGE_IPI 0x0103 +#define PCI_CLASS_STORAGE_RAID 0x0104 +#define PCI_CLASS_STORAGE_OTHER 0x0180 + +#define PCI_BASE_CLASS_NETWORK 0x02 +#define PCI_CLASS_NETWORK_ETHERNET 0x0200 +#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201 +#define PCI_CLASS_NETWORK_FDDI 0x0202 +#define PCI_CLASS_NETWORK_ATM 0x0203 +#define PCI_CLASS_NETWORK_OTHER 0x0280 + +#define PCI_BASE_CLASS_DISPLAY 0x03 +#define PCI_CLASS_DISPLAY_VGA 0x0300 +#define PCI_CLASS_DISPLAY_XGA 0x0301 +#define PCI_CLASS_DISPLAY_OTHER 0x0380 + +#define PCI_BASE_CLASS_MULTIMEDIA 0x04 +#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400 +#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401 +#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480 + + + +#define PCI_BASE_CLASS_MEMORY 0x05 +#define PCI_CLASS_MEMORY_RAM 0x0500 +#define PCI_CLASS_MEMORY_FLASH 0x0501 +#define PCI_CLASS_MEMORY_OTHER 0x0580 + +#define PCI_BASE_CLASS_BRIDGE 0x06 +#define PCI_CLASS_BRIDGE_HOST 0x0600 +#define PCI_CLASS_BRIDGE_ISA 0x0601 +#define PCI_CLASS_BRIDGE_EISA 0x0602 +#define PCI_CLASS_BRIDGE_MC 0x0603 +#define PCI_CLASS_BRIDGE_PCI 0x0604 +#define PCI_CLASS_BRIDGE_PCMCIA 0x0605 +#define PCI_CLASS_BRIDGE_NUBUS 0x0606 +#define PCI_CLASS_BRIDGE_CARDBUS 0x0607 +#define PCI_CLASS_BRIDGE_OTHER 0x0680 + +#define PCI_BASE_CLASS_COMMUNICATION 0x07 +#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700 +#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701 +#define PCI_CLASS_COMMUNICATION_OTHER 0x0780 + +#define PCI_BASE_CLASS_SYSTEM 0x08 +#define PCI_CLASS_SYSTEM_PIC 0x0800 +#define PCI_CLASS_SYSTEM_DMA 0x0801 +#define PCI_CLASS_SYSTEM_TIMER 0x0802 +#define PCI_CLASS_SYSTEM_RTC 0x0803 +#define PCI_CLASS_SYSTEM_OTHER 0x0880 + +#define PCI_BASE_CLASS_INPUT 0x09 +#define PCI_CLASS_INPUT_KEYBOARD 0x0900 +#define PCI_CLASS_INPUT_PEN 0x0901 +#define PCI_CLASS_INPUT_MOUSE 0x0902 +#define PCI_CLASS_INPUT_OTHER 0x0980 + +#define PCI_BASE_CLASS_DOCKING 0x0A +#define PCI_CLASS_DOCKING_GENERIC 0x0A00 +#define PCI_CLASS_DOCKING_OTHER 0x0A01 + +#define PCI_BASE_CLASS_PROCESSOR 0x0B +#define PCI_CLASS_PROCESSOR_386 0x0B00 +#define PCI_CLASS_PROCESSOR_486 0x0B01 +#define PCI_CLASS_PROCESSOR_PENTIUM 0x0B02 +#define PCI_CLASS_PROCESSOR_ALPHA 0x0B10 +#define PCI_CLASS_PROCESSOR_POWERPC 0x0B20 +#define PCI_CLASS_PROCESSOR_CO 0x0B40 + +#define PCI_BASE_CLASS_SERIAL 0x0C +#define PCI_CLASS_SERIAL_FIREWIRE 0x0C00 +#define PCI_CLASS_SERIAL_ACCESS 0x0C01 +#define PCI_CLASS_SERIAL_SSA 0x0C02 +#define PCI_CLASS_SERIAL_USB 0x0C03 +#define PCI_CLASS_SERIAL_FIBER 0x0C04 + +#define PCI_CLASS_HOT_SWAP_CONTROLLER 0xFF00 + +#define PCI_CLASS_OTHERS 0xFF + +#endif /* _PCI_PIO_H_ */ diff --git a/src/sys/include/types.h b/src/sys/include/types.h new file mode 100755 index 0000000..a60a74b --- /dev/null +++ b/src/sys/include/types.h @@ -0,0 +1,30 @@ +/* $Id$ */ + +#ifndef _TYPES_H_ +#define _TYPES_H_ + +#ifndef _BSD_TYPES_ +typedef unsigned char u_int8_t; +typedef unsigned short u_int16_t; +typedef unsigned int u_int32_t; +typedef unsigned long long int u_int64_t; +#endif /* _BSD_TYPES_ */ + +#ifndef _POSIX_TYPES_ +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned int u_int; +typedef unsigned long u_long; +typedef unsigned short ushort; /* Sys V */ +typedef unsigned int uint; /* Sys V */ +#endif /* POSIX_TYPES_ */ + +typedef signed char s8; +typedef signed short s16; +typedef signed long s32; + +typedef unsigned char u8; +typedef unsigned short u16; +typedef unsigned long u32; + +#endif /* _TYPES_H_ */ diff --git a/src/sys/include/ubixos/bios32.h b/src/sys/include/ubixos/bios32.h new file mode 100755 index 0000000..e2d49ef --- /dev/null +++ b/src/sys/include/ubixos/bios32.h @@ -0,0 +1,39 @@ +/* + * $Id$ + * + */ + +/* + * Copyright (C) by Johnny Zackrisson 2002. All rights reserved. + * + * You are free to do whatever you want with this code. + */ + +#ifndef _BIOS32_H__ +#define _BIOS32_H_ + +#define KERNEL_CS 0x8 +#define KERNEL_DS 0x10 + +#define BIOS32_MAKESIG(a, b, x, y) \ + ((a) | ((b) << 8) | ((x) << 16) | ((y) << 24)) + +void bios32_probe(); +//u32 pcibios_probe(); + +/* XXX: BSD types? */ +struct bios32_t { + unsigned long sign; + unsigned long entry; + unsigned char rev; + unsigned char len; + unsigned char cksum; + unsigned char res[5]; +}; + +struct bios32_entry_t { + unsigned long addr; + unsigned short sel; +}; + +#endif /* _BIOS32_H_ */ diff --git a/src/sys/kernel/bios32.c b/src/sys/kernel/bios32.c new file mode 100755 index 0000000..7be85b2 --- /dev/null +++ b/src/sys/kernel/bios32.c @@ -0,0 +1,78 @@ +/* $Id$ */ + +/* + * Copyright (c) 2002 Johnny Zackrisson. All rights reserved. + * + * You are free to do whatever you want with this code. + */ + +#include +#include + +/* These are physical addresses */ +#define BIOS32_START 0xe0000 +#define BIOS32_END 0xffff0 + +struct bios32_entry_t bios32_entry; + +void +bios32_probe() +{ + struct bios32_t *bios32 = (struct bios32_t *)BIOS32_START; + /* + unsigned char *cp; + int i; + */ + + /* + * XXX: phys2vir I/O mapping? + */ + for (; bios32 <= (struct bios32_t *)BIOS32_END; ++bios32) { + if ((bios32->sign == BIOS32_MAKESIG('_','3','2','_')) && + (bios32->len == 1) && (bios32->rev == 0)) { + + /* XXX XXX: Checksum calculation here! */ + /* + cp = (unsigned char *)bios32; + for (i=0; i<16; i++) + kprintf("%d ",cp[i]); + if (bios32->cksum != 0) + continue; + */ + + kprintf("BIOS32 Service Directory found at 0x%p\n" + "BIOS32 Entry: 0x%x Revision: %d Length: %d\n" + , bios32, bios32->entry, bios32->rev + , bios32->len); + return; + } + + if (bios32->entry != 0) { + bios32_entry.addr = bios32->entry; + bios32_entry.sel = KERNEL_CS; + } + } +} + +int +bios32_service(unsigned long service, struct bios32_entry_t *e) +{ + /* XXX: BSD types */ + unsigned long addr, len, entry; + unsigned char ret; + + __asm__ __volatile__("lcall *(%%edi)" + : "=a" (ret), "=b" (addr), "=c" (len), "=d" (entry) + : "0" (service), "1" (0), "D" (&bios32_entry) + ); + + /* XXX: care about 0x81? */ + if ((ret & 0xff) != 0) + return(-1); + else { + e->addr = (addr + entry); + e->sel = KERNEL_CS; + } + + return(0); +}