You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
(35) |
Dec
(2) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(37) |
Feb
(10) |
Mar
|
Apr
(2) |
May
(17) |
Jun
(1) |
Jul
(14) |
Aug
(14) |
Sep
(4) |
Oct
|
Nov
(14) |
Dec
(4) |
2005 |
Jan
(6) |
Feb
|
Mar
|
Apr
(6) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(1) |
Oct
|
Nov
(92) |
Dec
(12) |
2006 |
Jan
(3) |
Feb
(4) |
Mar
|
Apr
(5) |
May
(3) |
Jun
(15) |
Jul
(3) |
Aug
(1) |
Sep
(29) |
Oct
(1) |
Nov
(6) |
Dec
(5) |
2007 |
Jan
(2) |
Feb
(2) |
Mar
|
Apr
(3) |
May
(14) |
Jun
(2) |
Jul
(16) |
Aug
(73) |
Sep
(12) |
Oct
(9) |
Nov
(27) |
Dec
(3) |
2008 |
Jan
(4) |
Feb
(4) |
Mar
(3) |
Apr
(8) |
May
(23) |
Jun
(4) |
Jul
(1) |
Aug
(3) |
Sep
(7) |
Oct
(5) |
Nov
(1) |
Dec
(1) |
2009 |
Jan
|
Feb
(10) |
Mar
|
Apr
(4) |
May
(4) |
Jun
(10) |
Jul
|
Aug
(1) |
Sep
|
Oct
(7) |
Nov
|
Dec
(1) |
2010 |
Jan
|
Feb
(1) |
Mar
|
Apr
(6) |
May
|
Jun
(3) |
Jul
(11) |
Aug
(1) |
Sep
|
Oct
(15) |
Nov
(1) |
Dec
(5) |
2011 |
Jan
(4) |
Feb
(1) |
Mar
(6) |
Apr
|
May
(22) |
Jun
|
Jul
(8) |
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
(2) |
2012 |
Jan
|
Feb
(10) |
Mar
(1) |
Apr
(6) |
May
(27) |
Jun
(48) |
Jul
(30) |
Aug
(4) |
Sep
|
Oct
(3) |
Nov
(1) |
Dec
(11) |
2013 |
Jan
(4) |
Feb
(7) |
Mar
(6) |
Apr
(18) |
May
(28) |
Jun
(20) |
Jul
|
Aug
(4) |
Sep
(1) |
Oct
(1) |
Nov
(2) |
Dec
(7) |
2014 |
Jan
(3) |
Feb
(2) |
Mar
(4) |
Apr
(9) |
May
(11) |
Jun
(10) |
Jul
|
Aug
(18) |
Sep
(12) |
Oct
(17) |
Nov
(10) |
Dec
(16) |
2015 |
Jan
(5) |
Feb
(1) |
Mar
(5) |
Apr
(4) |
May
(28) |
Jun
(2) |
Jul
|
Aug
|
Sep
(6) |
Oct
|
Nov
(2) |
Dec
(1) |
2016 |
Jan
(14) |
Feb
|
Mar
(3) |
Apr
|
May
|
Jun
(3) |
Jul
(4) |
Aug
(4) |
Sep
(1) |
Oct
(1) |
Nov
|
Dec
(1) |
2017 |
Jan
(11) |
Feb
|
Mar
(21) |
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
(1) |
2018 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
(1) |
Jun
|
Jul
|
Aug
(2) |
Sep
(4) |
Oct
(4) |
Nov
|
Dec
(1) |
2019 |
Jan
(1) |
Feb
|
Mar
|
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
(13) |
Sep
(4) |
Oct
|
Nov
|
Dec
|
2020 |
Jan
(10) |
Feb
(9) |
Mar
(5) |
Apr
(4) |
May
(3) |
Jun
(18) |
Jul
(4) |
Aug
(2) |
Sep
(20) |
Oct
(2) |
Nov
|
Dec
|
2021 |
Jan
|
Feb
|
Mar
|
Apr
(2) |
May
(1) |
Jun
(2) |
Jul
(1) |
Aug
(2) |
Sep
|
Oct
|
Nov
|
Dec
(2) |
2022 |
Jan
(1) |
Feb
(2) |
Mar
(2) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
(5) |
Sep
|
Oct
(1) |
Nov
|
Dec
(1) |
2023 |
Jan
(10) |
Feb
(7) |
Mar
(29) |
Apr
(31) |
May
(29) |
Jun
(34) |
Jul
(3) |
Aug
(24) |
Sep
(22) |
Oct
(10) |
Nov
(38) |
Dec
(27) |
2024 |
Jan
(15) |
Feb
(8) |
Mar
(4) |
Apr
(20) |
May
(33) |
Jun
(18) |
Jul
(15) |
Aug
(23) |
Sep
(26) |
Oct
(32) |
Nov
(6) |
Dec
(4) |
2025 |
Jan
(7) |
Feb
(1) |
Mar
(1) |
Apr
(4) |
May
(46) |
Jun
(19) |
Jul
(26) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: Lawrence S. <ljs...@us...> - 2014-06-08 01:56:27
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 359c57ef6fba746c744f0dc0e770f7f88b48f486 (commit) from 1b72647afd30ab1762c13c8a98571b09d23d6717 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 359c57ef6fba746c744f0dc0e770f7f88b48f486 Author: Lawrence Sebald <ljs...@us...> Date: Sat Jun 7 21:56:01 2014 -0400 Fix formatting on getaddrinfo.c and update the CHANGELOG. ----------------------------------------------------------------------- Summary of changes: doc/CHANGELOG | 2 + kernel/libc/koslib/getaddrinfo.c | 1072 +++++++++++++++++++------------------- 2 files changed, 542 insertions(+), 532 deletions(-) diff --git a/doc/CHANGELOG b/doc/CHANGELOG index cc449f3..c2348d1 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -40,6 +40,8 @@ KallistiOS version 2.0.1 ----------------------------------------------- - DC Fixed full sector reading of non-data CDs (thanks to SWAT for pointing out that it needed fixing) [LS] - DC Added many new matrix/vector math-related macros [Josh Pearson = JP] +- *** Added libppp for dialup internet access to the addons tree [LS] +- *** Added DNS resolver functions getaddrinfo() and gethostbyname() [LS] KallistiOS version 2.0.0 ----------------------------------------------- - DC Broadband Adapter driver fixes [Dan Potter == DP] diff --git a/kernel/libc/koslib/getaddrinfo.c b/kernel/libc/koslib/getaddrinfo.c index d3ff836..7f52e8b 100644 --- a/kernel/libc/koslib/getaddrinfo.c +++ b/kernel/libc/koslib/getaddrinfo.c @@ -59,10 +59,10 @@ // These structs were all taken from RFC1035, page 26. typedef struct dnsmsg { - uint16_t id; // Can be anything - uint16_t flags; // Should have 0x0100 set for query, 0x8000 for response - uint16_t qdcount, ancount, nscount, arcount; - uint8_t data[]; // Payload + uint16_t id; // Can be anything + uint16_t flags; // Should have 0x0100 set for query, 0x8000 for response + uint16_t qdcount, ancount, nscount, arcount; + uint8_t data[]; // Payload } dnsmsg_t; static uint16_t qnum = 0; @@ -106,77 +106,77 @@ static uint16_t qnum = 0; PTR 12 MX 15 TXT 16 - AAAA 28 + AAAA 28 */ // Construct a DNS query for an A record by host name. "buf" should // be at least 1500 bytes, to make sure there's room. static size_t dns_make_query(const char *host, dnsmsg_t *buf, int ip4, - int ip6) { - int i, o = 0, ls, t; - - // Build up the header. - buf->id = htons(qnum++); - buf->flags = htons(0x0100); - buf->qdcount = htons(ip4 + ip6); - buf->ancount = htons(0); - buf->nscount = htons(0); - buf->arcount = htons(0); - - /* Fill in the question section(s). */ - ls = 0; - - if(ip4) { - o = ls + 1; - t = strlen(host); - - for(i = 0; i <= t; i++) { - if(host[i] == '.' || i == t) { - buf->data[ls] = (o - ls) - 1; - ls = o; - o++; - } - else { - buf->data[o++] = host[i]; - } - } - - buf->data[ls] = 0; - - // Might be unaligned now... so just build it by hand. - buf->data[o++] = (uint8_t)(QTYPE_A >> 8); - buf->data[o++] = (uint8_t)QTYPE_A; - buf->data[o++] = 0x00; - buf->data[o++] = 0x01; - ls = o; - } - - if(ip6) { - o = ls + 1; - t = strlen(host); - - for(i = 0; i <= t; i++) { - if(host[i] == '.' || i == t) { - buf->data[ls] = (o - ls) - 1; - ls = o; - o++; - } - else { - buf->data[o++] = host[i]; - } - } - - buf->data[ls] = 0; - - // Might be unaligned now... so just build it by hand. - buf->data[o++] = (uint8_t)(QTYPE_AAAA >> 8); - buf->data[o++] = (uint8_t)QTYPE_AAAA; - buf->data[o++] = 0x00; - buf->data[o++] = 0x01; - } - - // Return the full message size. - return (size_t)(o + sizeof(dnsmsg_t)); + int ip6) { + int i, o = 0, ls, t; + + // Build up the header. + buf->id = htons(qnum++); + buf->flags = htons(0x0100); + buf->qdcount = htons(ip4 + ip6); + buf->ancount = htons(0); + buf->nscount = htons(0); + buf->arcount = htons(0); + + /* Fill in the question section(s). */ + ls = 0; + + if(ip4) { + o = ls + 1; + t = strlen(host); + + for(i = 0; i <= t; i++) { + if(host[i] == '.' || i == t) { + buf->data[ls] = (o - ls) - 1; + ls = o; + o++; + } + else { + buf->data[o++] = host[i]; + } + } + + buf->data[ls] = 0; + + // Might be unaligned now... so just build it by hand. + buf->data[o++] = (uint8_t)(QTYPE_A >> 8); + buf->data[o++] = (uint8_t)QTYPE_A; + buf->data[o++] = 0x00; + buf->data[o++] = 0x01; + ls = o; + } + + if(ip6) { + o = ls + 1; + t = strlen(host); + + for(i = 0; i <= t; i++) { + if(host[i] == '.' || i == t) { + buf->data[ls] = (o - ls) - 1; + ls = o; + o++; + } + else { + buf->data[o++] = host[i]; + } + } + + buf->data[ls] = 0; + + // Might be unaligned now... so just build it by hand. + buf->data[o++] = (uint8_t)(QTYPE_AAAA >> 8); + buf->data[o++] = (uint8_t)QTYPE_AAAA; + buf->data[o++] = 0x00; + buf->data[o++] = 0x01; + } + + // Return the full message size. + return (size_t)(o + sizeof(dnsmsg_t)); } /* Resource records. A standard DNS response will have one query @@ -210,507 +210,515 @@ static size_t dns_make_query(const char *host, dnsmsg_t *buf, int ip4, // at the given offset. The new offset (after the label) will be // returned. static int dns_skip_label(dnsmsg_t *resp, int o) { - int cnt; + int cnt; - // End of the label? - while(resp->data[o] != 0) { - // Is it a pointer? - if((resp->data[o] & 0xc0) == 0xc0) - return o + 2; + // End of the label? + while(resp->data[o] != 0) { + // Is it a pointer? + if((resp->data[o] & 0xc0) == 0xc0) + return o + 2; - // Skip this part. - cnt = resp->data[o++]; - o += cnt; - } + // Skip this part. + cnt = resp->data[o++]; + o += cnt; + } - // Skip the terminator - o++; + // Skip the terminator + o++; - return o; + return o; } // Scans through and copies out a label in the data payload, // starting at the given offset. The new offset (after the label) // will be returned as well as the label string. static int dns_copy_label(dnsmsg_t *resp, int o, char *outbuf) { - int cnt; - int rv = -1; - - // Do each part. - outbuf[0] = 0; - - for(;;) { - // Is it a pointer? - if((resp->data[o] & 0xc0) == 0xc0) { - int offs = ((resp->data[o] & ~0xc0) << 8) | resp->data[o + 1]; - if (rv < 0) - rv = o + 2; - o = offs - sizeof(dnsmsg_t); - } - else { - cnt = resp->data[o++]; - if(cnt) { - if(outbuf[0] != 0) - strcat(outbuf, "."); - strncat(outbuf, (char *)(resp->data + o), cnt); - o += cnt; - } - else { - break; - } - } - } - - if(rv < 0) - return o; - else - return rv; + int cnt; + int rv = -1; + + // Do each part. + outbuf[0] = 0; + + for(;;) { + // Is it a pointer? + if((resp->data[o] & 0xc0) == 0xc0) { + int offs = ((resp->data[o] & ~0xc0) << 8) | resp->data[o + 1]; + + if(rv < 0) + rv = o + 2; + + o = offs - sizeof(dnsmsg_t); + } + else { + cnt = resp->data[o++]; + + if(cnt) { + if(outbuf[0] != 0) + strcat(outbuf, "."); + + strncat(outbuf, (char *)(resp->data + o), cnt); + o += cnt; + } + else { + break; + } + } + } + + if(rv < 0) + return o; + else + return rv; } /* Forward declaration... */ static struct addrinfo *add_ipv4_ai(uint32_t ip, uint16_t port, - struct addrinfo *h, struct addrinfo *tail); + struct addrinfo *h, struct addrinfo *tail); static struct addrinfo *add_ipv6_ai(const struct in6_addr *ip, uint16_t port, - struct addrinfo *h, struct addrinfo *tail); + struct addrinfo *h, struct addrinfo *tail); // Parse a response packet from the DNS server. The IP address // will be filled in upon a successful return, otherwise the // return value will be <0. static int dns_parse_response(dnsmsg_t *resp, struct addrinfo *hints, - uint16_t port, struct addrinfo **res) { - int i, o, arecs; - uint16_t flags; - char tmp[64]; - uint16_t ancnt, len; - struct addrinfo *ptr = NULL; - - /* Check the flags first to see if it was successful. */ - flags = ntohs(resp->flags); - if(!(flags & 0x8000)) { - /* Not our response! */ - return EAI_AGAIN; - } - - /* Did the server report an error? */ - switch(flags & 0x000f) { - case 0: /* No error */ - break; - - case 1: /* Format error */ - case 4: /* Not implemented */ - case 5: /* Refused */ - default: - return EAI_FAIL; - - case 3: /* Name error */ - return EAI_NONAME; - - case 2: /* Server failure */ - return EAI_AGAIN; - } - - /* Getting zero answers is also a failure. */ - ancnt = ntohs(resp->ancount); - if(ancnt < 1) - return EAI_NONAME; - - /* If we have any query sections (should have at least one), skip 'em. */ - o = 0; - len = ntohs(resp->qdcount); - for(i = 0; i < len; i++) { - /* Skip the label. */ - o = dns_skip_label(resp, o); - - /* And the two type fields. */ - o += 4; - } - - /* Ok, now the answer section (what we're interested in). */ - arecs = 0; - for(i = 0; i < ancnt; i++) { - /* Copy out the label, in case we need it. */ - o = dns_copy_label(resp, o, tmp); - - /* Get the type code. If it's not A or AAAA, skip it. */ - if(resp->data[o] == 0 && resp->data[o + 1] == 1 && - (hints->ai_family == AF_INET || hints->ai_family == AF_UNSPEC)) { - uint32_t addr; - - o += 8; - len = (resp->data[o] << 8) | resp->data[o + 1]; - o += 2; - - /* Grab the address from the response. */ - addr = htonl((resp->data[o] << 24) | (resp->data[o + 1] << 16) | - (resp->data[o + 2] << 8) | resp->data[o + 3]); - - /* Add this address to the chain. */ - if(!(ptr = add_ipv4_ai(addr, port, hints, ptr))) - /* If something goes wrong in here, it's in calling malloc, so - it is definitely a system error. */ - return EAI_SYSTEM; - - if(!*res) - *res = ptr; - - o += len; - arecs++; - } - else if(resp->data[o] == 0 && resp->data[o + 1] == 28 && - (hints->ai_family == AF_INET6 || hints->ai_family == AF_UNSPEC)) { - struct in6_addr addr; - - o += 8; - len = (resp->data[o] << 8) | resp->data[o + 1]; - o += 2; - - /* Grab the address from the response. */ - memcpy(addr.s6_addr, &resp->data[o], 16); - - /* Add this address to the chain. */ - if(!(ptr = add_ipv6_ai(&addr, port, hints, ptr))) - /* If something goes wrong in here, it's in calling malloc, so - it is definitely a system error. */ - return EAI_SYSTEM; - - if(!*res) - *res = ptr; - - o += len; - arecs++; - } - else if(resp->data[o] == 0 && resp->data[o + 1] == 5) { - char tmp2[64]; - - o += 8; - len = (resp->data[o] << 8) | resp->data[o + 1]; - o += 2; - o = dns_copy_label(resp, o, tmp2); - } - else { - o += 8; - len = (resp->data[o] << 8) | resp->data[o + 1]; - o += 2 + len; - } - } - - /* Did we find something? */ - return arecs > 0 ? 0 : EAI_NONAME; + uint16_t port, struct addrinfo **res) { + int i, o, arecs; + uint16_t flags; + char tmp[64]; + uint16_t ancnt, len; + struct addrinfo *ptr = NULL; + + /* Check the flags first to see if it was successful. */ + flags = ntohs(resp->flags); + + if(!(flags & 0x8000)) { + /* Not our response! */ + return EAI_AGAIN; + } + + /* Did the server report an error? */ + switch(flags & 0x000f) { + case 0: /* No error */ + break; + + case 1: /* Format error */ + case 4: /* Not implemented */ + case 5: /* Refused */ + default: + return EAI_FAIL; + + case 3: /* Name error */ + return EAI_NONAME; + + case 2: /* Server failure */ + return EAI_AGAIN; + } + + /* Getting zero answers is also a failure. */ + ancnt = ntohs(resp->ancount); + + if(ancnt < 1) + return EAI_NONAME; + + /* If we have any query sections (should have at least one), skip 'em. */ + o = 0; + len = ntohs(resp->qdcount); + + for(i = 0; i < len; i++) { + /* Skip the label. */ + o = dns_skip_label(resp, o); + + /* And the two type fields. */ + o += 4; + } + + /* Ok, now the answer section (what we're interested in). */ + arecs = 0; + + for(i = 0; i < ancnt; i++) { + /* Copy out the label, in case we need it. */ + o = dns_copy_label(resp, o, tmp); + + /* Get the type code. If it's not A or AAAA, skip it. */ + if(resp->data[o] == 0 && resp->data[o + 1] == 1 && + (hints->ai_family == AF_INET || hints->ai_family == AF_UNSPEC)) { + uint32_t addr; + + o += 8; + len = (resp->data[o] << 8) | resp->data[o + 1]; + o += 2; + + /* Grab the address from the response. */ + addr = htonl((resp->data[o] << 24) | (resp->data[o + 1] << 16) | + (resp->data[o + 2] << 8) | resp->data[o + 3]); + + /* Add this address to the chain. */ + if(!(ptr = add_ipv4_ai(addr, port, hints, ptr))) + /* If something goes wrong in here, it's in calling malloc, so + it is definitely a system error. */ + return EAI_SYSTEM; + + if(!*res) + *res = ptr; + + o += len; + arecs++; + } + else if(resp->data[o] == 0 && resp->data[o + 1] == 28 && + (hints->ai_family == AF_INET6 || hints->ai_family == AF_UNSPEC)) { + struct in6_addr addr; + + o += 8; + len = (resp->data[o] << 8) | resp->data[o + 1]; + o += 2; + ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-06-08 01:38:45
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 1b72647afd30ab1762c13c8a98571b09d23d6717 (commit) via d2a10ce57b5eb426bf8f75064309e1683922980d (commit) via f8b769a71e137738345eecc34b6e9cba6b5241ce (commit) from e1297146805c7aac51b569c6de616482bed822a3 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 1b72647afd30ab1762c13c8a98571b09d23d6717 Author: Lawrence Sebald <ljs...@us...> Date: Sat Jun 7 21:31:11 2014 -0400 Add getaddrinfo(), freeaddrinfo(), gethostbyname(), and gethosbyname2() functions. getaddrinfo() doesn't handle most of the flags available for it or service lookups by name, but it should be fine for its most common use (DNS lookups). gethostbyname() should be avoided, in general (it isn't thread safe, as it isn't required by POSIX to be), but was added for potential compatibility with code that uses it. gethostbyname2() is a GNU extension of gethostbyname() that allows you to specify the address family of addresses to be returned. Once again, it should be avoided for thread-safety concerns. commit d2a10ce57b5eb426bf8f75064309e1683922980d Author: Lawrence Sebald <ljs...@us...> Date: Sat Jun 7 00:56:16 2014 -0400 Fix another const-related thing in net_ipv4_frag. commit f8b769a71e137738345eecc34b6e9cba6b5241ce Author: Lawrence Sebald <ljs...@us...> Date: Fri Jun 6 19:01:13 2014 -0400 Add AF_UNSPEC and PF_UNSPEC to <sys/socket.h>. ----------------------------------------------------------------------- Summary of changes: include/netdb.h | 188 ++++++++++ include/sys/socket.h | 6 + kernel/libc/koslib/Makefile | 3 +- kernel/libc/koslib/getaddrinfo.c | 716 ++++++++++++++++++++++++++++++++++++ kernel/libc/koslib/gethostbyname.c | 182 +++++++++ kernel/net/net_ipv4_frag.c | 2 +- 6 files changed, 1095 insertions(+), 2 deletions(-) create mode 100644 include/netdb.h create mode 100644 kernel/libc/koslib/getaddrinfo.c create mode 100644 kernel/libc/koslib/gethostbyname.c diff --git a/include/netdb.h b/include/netdb.h new file mode 100644 index 0000000..19e4232 --- /dev/null +++ b/include/netdb.h @@ -0,0 +1,188 @@ +/* KallistiOS ##version## + + netdb.h + Copyright (C) 2014 Lawrence Sebald + +*/ + +/** \file netdb.h + \brief Network address database functionality. + + This file contains functions related to network address lookups, usually + performed through DNS. + + \author Lawrence Sebald +*/ + +#ifndef __NETDB_H +#define __NETDB_H + +#include <sys/cdefs.h> + +__BEGIN_DECLS + +#include <netinet/in.h> +#include <sys/socket.h> +#include <inttypes.h> + +/** \brief Network host entry. + + This structure describes a network host entry in the address database. When + looking up an address with the gethostbyname() function, one of these will + be returned with information about the host. + + \headerfile netdb.h +*/ +struct hostent { + char *h_name; /**< \brief Official name of the host. */ + char **h_aliases; /**< \brief Alternative host names. */ + int h_addrtype; /**< \brief Address type. */ + int h_length; /**< \brief Length of address, in bytes. */ + char **h_addr_list; /**< \brief Network addresses of host. */ +#define h_addr h_addr_list[0] /**< \brief Primary network address. */ +}; + +/** \brief Network address information structure. + + This structure describes information on an address in the database. This + structure is used by functions such as getaddrinfo() to return information + about the specified host. + + \headerfile netdb.h +*/ +struct addrinfo { + int ai_flags; /**< \brief Input flags. + \see addrinfo_flags */ + int ai_family; /**< \brief Socket address family. */ + int ai_socktype; /**< \brief Socket type. */ + int ai_protocol; /**< \brief Socket protocol. */ + socklen_t ai_addrlen; /**< \brief Address length. */ + struct sockaddr *ai_addr; /**< \brief Address structure. */ + char *ai_canonname; /**< \brief Canonical name. */ + struct addrinfo *ai_next; /**< \brief Next address entry (if any). */ +}; + +/** \brief Error value for gethostbyname(). + \see herrno_vals */ +extern int h_errno; + +/** \defgroup herrno_vals Error values for the h_errno variable + + These are the possible values for h_errno, indicating errors returns from + the gethostbyname() function. + + @{ +*/ +#define HOST_NOT_FOUND 1 /**< \brief Hostname not found. */ +#define TRY_AGAIN 2 /**< \brief Try the request again. */ +#define NO_RECOVERY 3 /**< \brief A non-recoverable error. */ +#define NO_DATA 4 /**< \brief Host found, but no data. */ +/** @} */ + +/** \defgroup addrinfo_errors Errors for the getaddrinfo() function + + These are the possible error return values from the getaddrinfo() function. + + @{ +*/ +#define EAI_AGAIN 1 /**< \brief Try the request again. */ +#define EAI_BADFLAGS 2 /**< \brief Invalid hint flags. */ +#define EAI_FAIL 3 /**< \brief A non-recoverable error. */ +#define EAI_FAMILY 4 /**< \brief Invalid address family. */ +#define EAI_MEMORY 5 /**< \brief Memory allocation error. */ +#define EAI_NONAME 6 /**< \brief Hostname not found. */ +#define EAI_SERVICE 7 /**< \brief Invalid service value. */ +#define EAI_SOCKTYPE 8 /**< \brief Invalid socket type. */ +#define EAI_SYSTEM 9 /**< \brief System error, check errno. */ +#define EAI_OVERFLOW 10 /**< \brief Argument buffer overflow. */ +/** @} */ + +/** \defgroup addrinfo_flags Flags for ai_flags in struct addrinfo + + These are the flags that can be set in the ai_flags field of struct + addrinfo. These values can be bitwise ORed together. + + Currently only AI_PASSIVE is actually supported by the getaddrinfo() + function. + + @{ +*/ +#define AI_PASSIVE 0x00000001 /**< \brief Address intended for bind(). */ +#define AI_CANONNAME 0x00000002 /**< \brief Request canonical name. */ +#define AI_NUMERICHOST 0x00000004 /**< \brief Inhibit host resolution. */ +#define AI_NUMERICSERV 0x00000008 /**< \brief Inhibit service resolution. */ +#define AI_V4MAPPED 0x00000010 /**< \brief Return v4-mapped IPv6 addrs. */ +#define AI_ALL 0x00000020 /**< \brief Query for both IPv4 and IPv6. */ +#define AI_ADDRCONFIG 0x00000040 /**< \brief Only query for IPv4/IPv6 addrs + the system has a valid addr. */ +/** @} */ + +/** \brief Free an address information structure returned by getaddrinfo(). + + This function cleans up any memory associated with the specified + struct addrinfo, which was returned previously by a call to getaddrinfo(). + + \param ai The struct addrinfo to clean up. +*/ +void freeaddrinfo(struct addrinfo *ai); + +/** \brief Get information about a specified addresss. + + This function translates the name of a host and service into a set of socket + addresses and related information to be used in creating a socket. This + includes potentially looking up the host information in the network address + database (and thus in DNS possibly as well). + + \param nodename The host to look up. + \param servname The service to look up. + \param hints Hints used in aiding lookup. + \param res The resulting address information. + \return 0 on success, non-zero error code on failure. + \see addrinfo_errors +*/ +int getaddrinfo(const char *nodename, const char *servname, + const struct addrinfo *hints, struct addrinfo **res); + +/** \brief Look up a host by its name. + + This function queries the network address database (possibly recursively) + for the network address of the specified hostname. This will first search + any local databases before querying remote databases (such as a DNS server) + for the host specified. + + \param name The hostname to look up. + \return A pointer to a host entry on success or NULL on + failure. h_errno is set on failure to indicate the + error that occurred. + + \note This function is non-reentrant. getaddrinfo() should + (in general) be used instead of this function. +*/ +struct hostent *gethostbyname(const char *name); + +/** \brief Look up a host by its name and address family. + + This function queries the network address database (possibly recursively) + for the network address of the specified hostname. This will first search + any local databases before querying remote databases (such as a DNS server) + for the host specified. + + This function allows you to specify the address family that you wish the + returned hostent to contain. This function is a GNU extension and has not + been specified by any POSIX specification. + + \param name The hostname to look up. + \param af The address family to use for lookups (AF_INET or + AF_INET6). + \return A pointer to a host entry on success or NULL on + failure. h_errno is set on failure to indicate the + error that occurred. + + \note This function is non-reentrant. getaddrinfo() should + (in general) be used instead of this function. +*/ +struct hostent *gethostbyname2(const char *name, int af); + +__END_DECLS + +#endif /* !__NETDB_H */ diff --git a/include/sys/socket.h b/include/sys/socket.h index 95c823c..4b395d7 100644 --- a/include/sys/socket.h +++ b/include/sys/socket.h @@ -156,12 +156,18 @@ struct sockaddr_storage { #define MSG_DONTWAIT 0x80 /**< \brief Make this call non-blocking (non-standard) */ /** @} */ +/** \brief Unspecified address family. */ +#define AF_UNSPEC 0 + /** \brief Internet domain sockets for use with IPv4 addresses. */ #define AF_INET 1 /** \brief Internet domain sockets for use with IPv6 addresses. */ #define AF_INET6 2 +/** \brief Unspecified protocol family. */ +#define PF_UNSPEC AF_UNSPEC + /** \brief Protocol family for Internet domain sockets (IPv4). */ #define PF_INET AF_INET diff --git a/kernel/libc/koslib/Makefile b/kernel/libc/koslib/Makefile index ad9217e..2b3d0c9 100644 --- a/kernel/libc/koslib/Makefile +++ b/kernel/libc/koslib/Makefile @@ -12,6 +12,7 @@ OBJS = abort.o byteorder.o memset2.o memset4.o memcpy2.o memcpy4.o \ opendir.o readdir.o closedir.o rewinddir.o scandir.o seekdir.o \ telldir.o usleep.o inet_addr.o realpath.o getcwd.o chdir.o mkdir.o \ creat.o sleep.o rmdir.o rename.o inet_pton.o inet_ntop.o \ - inet_ntoa.o inet_aton.o poll.o select.o symlink.o readlink.o + inet_ntoa.o inet_aton.o poll.o select.o symlink.o readlink.o \ + gethostbyname.o getaddrinfo.o include $(KOS_BASE)/Makefile.prefab diff --git a/kernel/libc/koslib/getaddrinfo.c b/kernel/libc/koslib/getaddrinfo.c new file mode 100644 index 0000000..d3ff836 --- /dev/null +++ b/kernel/libc/koslib/getaddrinfo.c @@ -0,0 +1,716 @@ +/* KallistiOS ##version## + + getaddrinfo.c + + Copyright (C) 2014 Lawrence Sebald + + Originally: + lwip/dns.c + Copyright (C) 2004 Dan Potter +*/ + +/* The actual code for querying the DNS was taken from the old kos-ports lwIP + port, and was originally written by Dan. This has been modified/extended a + bit. The old lwip_gethostbyname() function was reworked a lot to create the + new getaddrinfo_dns() function. In addition, the dns_parse_response() + function got a bit of a makeover too. + + The implementations of getaddrinfo() and freeaddrinfo() are new to this + version of the code though. + + Eventually, I'd like to add some sort of cacheing of results to this file so + that if you look something up more than once, it doesn't have to go back out + to the server to do so. But, for now, there is no local database of cached + addresses... +*/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <kos/dbglog.h> + +#include <netdb.h> +#include <sys/socket.h> +#include <arpa/inet.h> +#include <netinet/in.h> + +#include <kos/net.h> + +#define printf(...) dbglog(DBG_KDEBUG, __VA_ARGS__); + +/* + This performs a simple DNS A-record query. It hasn't been tested extensively + but so far it seems to work fine. + + This relies on the really sketchy UDP support in the KOS lwIP port, so it + can be cleaned up later once that's improved. + + We really need to be setting errno in here too... + */ + + + +/* Basic query process: + + - Send a DNS message to the server on port 53, with one query payload. + - Receive DNS message from port 53 with one or more answer payloads (hopefully). + */ + +// These structs were all taken from RFC1035, page 26. +typedef struct dnsmsg { + uint16_t id; // Can be anything + uint16_t flags; // Should have 0x0100 set for query, 0x8000 for response + uint16_t qdcount, ancount, nscount, arcount; + uint8_t data[]; // Payload +} dnsmsg_t; + +static uint16_t qnum = 0; + +#define QTYPE_A 1 +#define QTYPE_AAAA 28 + +/* Flags: + Query/Response (1 bit) -- 0 = Query, 1 = Response + Opcode (4 bits) -- 0 = Standard, 1 = Inverse, 2 = Status + AA (1 bit) -- authoritative answer + TC (1 bit) -- truncated message + RD (1 bit) -- recursion desired + RA (1 bit) -- recursion available + Z (1 bit) -- zero + RCODE (4 bits) -- 0 = No Error, >0 = Error + + Generally a query will have 0x0100 here, and a typical + response will have 0x8180. +*/ + +/* Query section. A standard DNS query will have one query section + and no other payloads. There is no padding. + + QNAME: one or more "labels", representing a domain name. For + example "yuna.dp.allusion.net" is "yuna, dp, allusion, net". Each + label has one length byte followed by N data bytes. A zero + length byte terminates. + + QTYPE: two-byte code specifying the RR type of the query. For a + normal DNS query this should be 0x0001 (A - IPv4) or 0x001C (AAAA - IPv6). + + QCLASS: two-byte code specifying the class of the query. For a + normal DNS query this should be 0x0001 (IN). + + Common RR types: + A 1 + NS 2 + CNAME 5 + SOA 6 + PTR 12 + MX 15 + TXT 16 + AAAA 28 + */ + +// Construct a DNS query for an A record by host name. "buf" should +// be at least 1500 bytes, to make sure there's room. +static size_t dns_make_query(const char *host, dnsmsg_t *buf, int ip4, + int ip6) { + int i, o = 0, ls, t; + + // Build up the header. + buf->id = htons(qnum++); + buf->flags = htons(0x0100); + buf->qdcount = htons(ip4 + ip6); + buf->ancount = htons(0); + buf->nscount = htons(0); + buf->arcount = htons(0); + + /* Fill in the question section(s). */ + ls = 0; + + if(ip4) { + o = ls + 1; + t = strlen(host); + + for(i = 0; i <= t; i++) { + if(host[i] == '.' || i == t) { + buf->data[ls] = (o - ls) - 1; + ls = o; + o++; + } + else { + buf->data[o++] = host[i]; + } + } + + buf->data[ls] = 0; + + // Might be unaligned now... so just build it by hand. + buf->data[o++] = (uint8_t)(QTYPE_A >> 8); + buf->data[o++] = (uint8_t)QTYPE_A; + buf->data[o++] = 0x00; + buf->data[o++] = 0x01; + ls = o; + } + + if(ip6) { + o = ls + 1; + t = strlen(host); + + for(i = 0; i <= t; i++) { + if(host[i] == '.' || i == t) { + buf->data[ls] = (o - ls) - 1; + ls = o; + o++; + } + else { + buf->data[o++] = host[i]; + } + } + + buf->data[ls] = 0; + + // Might be unaligned now... so just build it by hand. + buf->data[o++] = (uint8_t)(QTYPE_AAAA >> 8); + buf->data[o++] = (uint8_t)QTYPE_AAAA; + buf->data[o++] = 0x00; + buf->data[o++] = 0x01; + } + + // Return the full message size. + return (size_t)(o + sizeof(dnsmsg_t)); +} + +/* Resource records. A standard DNS response will have one query + section (the original one) plus an answer section. It may have + other sections but these can be ignored. + + NAME: Same as QNAME, with one caveat (see below). + TYPE: Two-byte RR code (same as QTYPE). + CLASS: Two-byte class code (same as QCLASS). + TTL: Four-byte time to live interval in seconds; this entry should + not be cached longer than this. + RDLENGTH: Two-byte response length (in bytes). + RDATA: Response data, size is RDLENGTH. + + For "NAME", note that this may also be a "back pointer". This is + to save space in DNS queries. Back pointers are 16-bit values with + the upper two bits set to one, and the lower bits representing an + offset within the full DNS message. So e.g., 0xc00c for the NAME + means to look at offset 12 in the full message to find the NAME + record. + + For A records, RDLENGTH is 4 and RDATA is a 4-byte IP address. + + When doing queries on the internet you may also get back CNAME + entries. In these responses you may have more than one answer + section (e.g. a 5 and a 1). The CNAME answer will contain the real + name, and the A answer contains the address. + */ + +// Scans through and skips a label in the data payload, starting +// at the given offset. The new offset (after the label) will be +// returned. +static int dns_skip_label(dnsmsg_t *resp, int o) { + int cnt; + + // End of the label? + while(resp->data[o] != 0) { + // Is it a pointer? + if((resp->data[o] & 0xc0) == 0xc0) + return o + 2; + + // Skip this part. + cnt = resp->data[o++]; + o += cnt; + } + + // Skip the terminator + o++; + + return o; +} + +// Scans through and copies out a label in the data payload, +// starting at the given offset. The new offset (after the label) +// will be returned as well as the label string. +static int dns_copy_label(dnsmsg_t *resp, int o, char *outbuf) { + int cnt; + int rv = -1; + + // Do each part. + outbuf[0] = 0; + + for(;;) { + // Is it a pointer? + if((resp->data[o] & 0xc0) == 0xc0) { + int offs = ((resp->data[o] & ~0xc0) << 8) | resp->data[o + 1]; + if (rv < 0) + rv = o + 2; + o = offs - sizeof(dnsmsg_t); + } + else { + cnt = resp->data[o++]; + if(cnt) { + if(outbuf[0] != 0) + strcat(outbuf, "."); + strncat(outbuf, (char *)(resp->data + o), cnt); + o += cnt; + } + else { + break; + } + } + } + + if(rv < 0) + return o; ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-06-05 22:04:52
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via e1297146805c7aac51b569c6de616482bed822a3 (commit) from f39949974686b1245b73d0c24306a90b3829125d (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e1297146805c7aac51b569c6de616482bed822a3 Author: Lawrence Sebald <ljs...@us...> Date: Thu Jun 5 18:03:41 2014 -0400 Add support for using the modem with libppp. Please note: I haven't tested this with a real ISP. I have tested this with a phone line simulator and a Netopia R2020 router, which works fine. ----------------------------------------------------------------------- Summary of changes: addons/include/ppp/ppp.h | 21 ++++++ addons/libppp/kos/dreamcast.cnf | 2 +- addons/libppp/ppp_modem.c | 128 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+), 1 deletions(-) create mode 100644 addons/libppp/ppp_modem.c diff --git a/addons/include/ppp/ppp.h b/addons/include/ppp/ppp.h index b1294f9..4d02945 100644 --- a/addons/include/ppp/ppp.h +++ b/addons/include/ppp/ppp.h @@ -361,6 +361,27 @@ int ppp_connect(void); */ int ppp_scif_init(int bps); +/** \brief Initialize the Dreamcast modem for a PPP link. + + This function sets up the Dreamcast serial port to act as a communications + link for a point-to-point connection. This includes dialing the specified + phone number and establishing the low-level link. + + \param number The phone number to dial out. + \param blind Non-zero to blind dial (don't wait for a dial tone). + \param conn_rate Storage for the connection rate, in bits per second. Set + to NULL if you do not need this value back from the + function. + \retval 0 On success. + \retval -1 If modem initialization fails. + \retval -2 If not using blind dial and no dial tone is detected + within 5 seconds of opening the line. + \retval -3 If dialing the modem fails. + \retval -4 If a connection is not established in 60 seconds after + dialing. +*/ +int ppp_modem_init(const char *number, int blind, int *conn_rate); + /** \brief Initialize the PPP library. This function initializes the PPP library, preparing internal structures for diff --git a/addons/libppp/kos/dreamcast.cnf b/addons/libppp/kos/dreamcast.cnf index e28d567..9f7065a 100644 --- a/addons/libppp/kos/dreamcast.cnf +++ b/addons/libppp/kos/dreamcast.cnf @@ -1 +1 @@ -OBJS += ppp_scif.o +OBJS += ppp_scif.o ppp_modem.o diff --git a/addons/libppp/ppp_modem.c b/addons/libppp/ppp_modem.c new file mode 100644 index 0000000..ddcaa05 --- /dev/null +++ b/addons/libppp/ppp_modem.c @@ -0,0 +1,128 @@ +/* KallistiOS ##version## + + libppp/ppp_modem.c + Copyright (C) 2014 Lawrence Sebald +*/ + +#include <stdio.h> +#include <stdint.h> + +#include <kos/dbglog.h> + +#include <arch/timer.h> + +#include <dc/modem/modem.h> + +#include <ppp/ppp.h> + +static int ppp_modem_detect_init(ppp_device_t *self) { + (void)self; + + return 0; +} + +static int ppp_modem_shutdown(ppp_device_t *self) { + (void)self; + + if(modem_is_connected()) + modem_disconnect(); + + modem_shutdown(); + return 0; +} + +static int ppp_modem_tx(ppp_device_t *self, const uint8_t *data, size_t len, + uint32_t flags) { + size_t done = 0; + (void)self; + (void)flags; + + /* As long as we have something to send, do so. */ + while(done < len) { + done += modem_write_data((unsigned char *)data + done, (int)len - done); + } + + return 0; +} + +static const uint8_t *ppp_modem_rx(ppp_device_t *self, ssize_t *out_len) { + static uint8_t rb[1024]; + int cnt = 0; + + (void)self; + + /* Read anything that's waiting. */ + cnt = modem_read_data((unsigned char *)rb, 1024); + + /* If we got anything, return what we got. */ + if(cnt) { + *out_len = (ssize_t)cnt; + return rb; + } + + *out_len = 0; + return NULL; +} + +static ppp_device_t modem_dev = { + "modem", /* name */ + "PPP over Dreamcast Modem", /* descr */ + 0, /* index */ + 0, /* flags */ + NULL, /* privdata */ + &ppp_modem_detect_init, /* detect */ + &ppp_modem_detect_init, /* init */ + &ppp_modem_shutdown, /* shutdown */ + &ppp_modem_tx, /* tx */ + &ppp_modem_rx /* rx */ +}; + +int ppp_modem_init(const char *number, int blind, int *conn_rate) { + uint64_t timeout; + + /* Initialize the modem. */ + if(!modem_init()) + return -1; + + /* Set the modem up to connect to a remote machine. */ + modem_set_mode(MODEM_MODE_REMOTE, MODEM_SPEED_V8_AUTO); + + /* If we aren't doing blind dialing, wait up to 5 seconds for a dialtone. */ + if(!blind) { + if(modem_wait_dialtone(5000)) { + modem_shutdown(); + return -2; + } + } + + /* Dial the specified phone number. */ + if(!modem_dial(number)) { + modem_shutdown(); + return -3; + } + + /* Give ourselves a 60 second timeout to establish a connection. */ + timeout = timer_ms_gettime64() + 60 * 1000; + while(timer_ms_gettime64() < timeout && modem_is_connecting()) { + thd_pass(); + } + + /* Did we connect successfully? */ + if(!modem_is_connected()) { + modem_shutdown(); + return -4; + } + + /* Does the user want the connection rate back? If so give it to them. */ + if(conn_rate) { + *conn_rate = modem_get_connection_rate(); + } + + dbglog(DBG_KDEBUG, "ppp_modem: connected at %lu bps\n", + modem_get_connection_rate()); + + /* We connected to the peer successfully, set our device with libppp. */ + ppp_set_device(&modem_dev); + + return 0; +} hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-06-05 22:02:59
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via f39949974686b1245b73d0c24306a90b3829125d (commit) from 39f27ff330285443745a363ab2478e6959b82b02 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f39949974686b1245b73d0c24306a90b3829125d Author: Lawrence Sebald <ljs...@us...> Date: Thu Jun 5 18:02:34 2014 -0400 Correctly request the DNS from the other side of the link. ----------------------------------------------------------------------- Summary of changes: addons/libppp/ipcp.c | 66 +++++++++++++++++++++++++++++++++---------------- 1 files changed, 44 insertions(+), 22 deletions(-) diff --git a/addons/libppp/ipcp.c b/addons/libppp/ipcp.c index 5d1d38a..0dce932 100644 --- a/addons/libppp/ipcp.c +++ b/addons/libppp/ipcp.c @@ -55,12 +55,21 @@ static int ipcp_send_client_cfg(ppp_protocol_t *self, int resend) { uint8_t rawpkt[100]; ipcp_pkt_t *pkt = (ipcp_pkt_t *)rawpkt; int len = 0; - uint32_t addr = 0; + uint8_t addr[4] = { 0, 0, 0, 0 }, dns[4] = { 0, 0, 0, 0 }; (void)self; - if(ipcp_state.ppp_state->netif) - addr = (uint32_t)net_ipv4_address(ipcp_state.ppp_state->netif->ip_addr); + if(ipcp_state.ppp_state->netif) { + addr[0] = ipcp_state.ppp_state->netif->ip_addr[0]; + addr[1] = ipcp_state.ppp_state->netif->ip_addr[1]; + addr[2] = ipcp_state.ppp_state->netif->ip_addr[2]; + addr[3] = ipcp_state.ppp_state->netif->ip_addr[3]; + + dns[0] = ipcp_state.ppp_state->netif->dns[0]; + dns[1] = ipcp_state.ppp_state->netif->dns[1]; + dns[2] = ipcp_state.ppp_state->netif->dns[2]; + dns[3] = ipcp_state.ppp_state->netif->dns[3]; + } /* Fill in the code and identifier, then move onto the data. We'll get the length when we're done with the data. */ @@ -73,10 +82,17 @@ static int ipcp_send_client_cfg(ppp_protocol_t *self, int resend) { pkt->data[len++] = IPCP_CONFIGURE_IP_ADDRESS; pkt->data[len++] = 6; - pkt->data[len++] = (uint8_t)(addr >> 24); - pkt->data[len++] = (uint8_t)(addr >> 16); - pkt->data[len++] = (uint8_t)(addr >> 8); - pkt->data[len++] = (uint8_t)addr; + pkt->data[len++] = addr[0]; + pkt->data[len++] = addr[1]; + pkt->data[len++] = addr[2]; + pkt->data[len++] = addr[3]; + + pkt->data[len++] = IPCP_CONFIGURE_PRIMARY_DNS; + pkt->data[len++] = 6; + pkt->data[len++] = dns[0]; + pkt->data[len++] = dns[1]; + pkt->data[len++] = dns[2]; + pkt->data[len++] = dns[3]; len += 4; pkt->len = htons(len); @@ -145,7 +161,7 @@ static int ipcp_handle_configure_req(ppp_protocol_t *self, uint8_t response_len = 4, nak_len = 4; /* Parameters and their default values. */ - uint32_t addr = 0, dns1 = 0, dns2 = 0; + uint32_t addr = 0; (void)pkt; @@ -213,9 +229,6 @@ static int ipcp_handle_configure_req(ppp_protocol_t *self, case IPCP_CONFIGURE_PRIMARY_DNS: if(opt_len == 6) { - dns2 = (pkt->data[ptr + 2] << 24) | - (pkt->data[ptr + 3] << 16) | (pkt->data[ptr + 4] << 8) | - pkt->data[ptr + 5]; DBG(" primary DNS: %d.%d.%d.%d\n", (int)pkt->data[ptr + 2], (int)pkt->data[ptr + 3], (int)pkt->data[ptr + 4], (int)pkt->data[ptr + 5]); @@ -240,9 +253,6 @@ static int ipcp_handle_configure_req(ppp_protocol_t *self, case IPCP_CONFIGURE_SECONDARY_DNS: if(opt_len == 6) { - dns2 = (pkt->data[ptr + 2] << 24) | - (pkt->data[ptr + 3] << 16) | (pkt->data[ptr + 4] << 8) | - pkt->data[ptr + 5]; DBG(" secondary DNS: %d.%d.%d.%d\n", (int)pkt->data[ptr + 2], (int)pkt->data[ptr + 3], (int)pkt->data[ptr + 4], (int)pkt->data[ptr + 5]); @@ -297,13 +307,6 @@ reject_opt: nif->gateway[1] = (uint8)(addr >> 16); nif->gateway[2] = (uint8)(addr >> 8); nif->gateway[3] = (uint8)addr; - - nif->dns[0] = (uint8)(dns1 >> 24); - nif->dns[1] = (uint8)(dns1 >> 16); - nif->dns[2] = (uint8)(dns1 >> 8); - nif->dns[3] = (uint8)dns1; - - (void)dns2; } if(ipcp_state.state == PPP_STATE_ACK_RECEIVED) { @@ -410,7 +413,7 @@ static int ipcp_handle_configure_ack(ppp_protocol_t *self, static int ipcp_handle_configure_nak(ppp_protocol_t *self, const ipcp_pkt_t *pkt, size_t len) { - uint32_t addr = 0; + uint32_t addr = 0, dns = 0; size_t ptr = 0; uint8_t opt_len; @@ -487,6 +490,20 @@ static int ipcp_handle_configure_nak(ppp_protocol_t *self, } break; + case IPCP_CONFIGURE_PRIMARY_DNS: + if(opt_len == 6) { + dns = (pkt->data[ptr + 2] << 24) | + (pkt->data[ptr + 3] << 16) | (pkt->data[ptr + 4] << 8) | + pkt->data[ptr + 5]; + DBG(" DNS 1: %d.%d.%d.%d\n", (int)pkt->data[ptr + 2], + (int)pkt->data[ptr + 3], (int)pkt->data[ptr + 4], + (int)pkt->data[ptr + 5]); + } + else { + DBG(" DNS 1 (bad length)\n"); + } + break; + /* If we don't know about the option, ignore it. */ default: DBG(" unknown option: %d (len %d)\n", pkt->data[ptr], @@ -505,6 +522,11 @@ static int ipcp_handle_configure_nak(ppp_protocol_t *self, nif->ip_addr[1] = (uint8)(addr >> 16); nif->ip_addr[2] = (uint8)(addr >> 8); nif->ip_addr[3] = (uint8)addr; + + nif->dns[0] = (uint8)(dns >> 24); + nif->dns[1] = (uint8)(dns >> 16); + nif->dns[2] = (uint8)(dns >> 8); + nif->dns[3] = (uint8)dns; } return ipcp_send_client_cfg(self, 0); hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-06-05 01:53:32
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 39f27ff330285443745a363ab2478e6959b82b02 (commit) via bcbabec490cdad45499abeecfb0fe18b4a8dd970 (commit) from 38a612d447f0f2b5e533dd2cbb75d9f489652f7e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 39f27ff330285443745a363ab2478e6959b82b02 Author: Lawrence Sebald <ljs...@us...> Date: Wed Jun 4 21:51:17 2014 -0400 Add libppp for PPP support in the network stack. Note: This currently does not support the modem. Currently the library supports PPP connections over a Coder's Cable (or similar). Modem support will come relatively soon, once I get a chance to write and test the code. ;-) commit bcbabec490cdad45499abeecfb0fe18b4a8dd970 Author: Lawrence Sebald <ljs...@us...> Date: Wed Jun 4 18:35:11 2014 -0400 Fix some things in IPv4 to be const-correct. ----------------------------------------------------------------------- Summary of changes: addons/include/ppp/ppp.h | 383 ++++++++++++++ addons/libppp/Makefile | 13 + addons/libppp/fcs.h | 50 ++ addons/libppp/ipcp.c | 711 ++++++++++++++++++++++++++ addons/libppp/kos/dreamcast.cnf | 1 + addons/libppp/lcp.c | 1043 +++++++++++++++++++++++++++++++++++++++ addons/libppp/pap.c | 175 +++++++ addons/libppp/ppp.c | 714 +++++++++++++++++++++++++++ addons/libppp/ppp_internal.h | 116 +++++ addons/libppp/ppp_scif.c | 102 ++++ kernel/net/net_icmp.c | 6 +- kernel/net/net_icmp.h | 3 +- kernel/net/net_ipv4.c | 17 +- kernel/net/net_ipv4.h | 4 +- kernel/net/net_ipv4_frag.c | 4 +- 15 files changed, 3323 insertions(+), 19 deletions(-) create mode 100644 addons/include/ppp/ppp.h create mode 100644 addons/libppp/Makefile create mode 100644 addons/libppp/fcs.h create mode 100644 addons/libppp/ipcp.c create mode 100644 addons/libppp/kos/dreamcast.cnf create mode 100644 addons/libppp/lcp.c create mode 100644 addons/libppp/pap.c create mode 100644 addons/libppp/ppp.c create mode 100644 addons/libppp/ppp_internal.h create mode 100644 addons/libppp/ppp_scif.c diff --git a/addons/include/ppp/ppp.h b/addons/include/ppp/ppp.h new file mode 100644 index 0000000..b1294f9 --- /dev/null +++ b/addons/include/ppp/ppp.h @@ -0,0 +1,383 @@ +/* KallistiOS ##version## + + ppp/ppp.h + Copyright (C) 2014 Lawrence Sebald +*/ + +#ifndef __PPP_PPP_H +#define __PPP_PPP_H + +#include <sys/cdefs.h> +__BEGIN_DECLS + +#include <stdint.h> +#include <sys/types.h> +#include <sys/queue.h> + +/** \file ppp/ppp.h + \brief PPP interface for network communications. + + This file defines the API provided by libppp to interact with the PPP stack. + PPP is a network communication protocol used to establish a direct link + between two peers. It is most commonly used as the data link layer protocol + for dialup internet access, but can also be potentially used on broadband + connections (PPP over Ethernet or PPPoE) or on a direct serial line to + a computer. + + The API presented by this library is designed to be extensible to whatever + devices you might want to use it with, and was designed to integrate fairly + simply into the rest of KOS' network stack. + + \author Lawrence Sebald +*/ + +/** \brief PPP device structure. + + This structure defines a basic output device for PPP packets. This structure + is largely modeled after netif_t from the main network stack, with a bit of + functionality removed that is irrelevant for PPP. + + Note that we only allow one device and one connection in this library. + + \headerfile ppp/ppp.h +*/ +typedef struct ppp_device { + /** \brief Device name ("modem", "scif", etc). */ + const char *name; + + /** \brief Long description of the device. */ + const char *descr; + + /** \brief Unit index (starts at zero and counts upwards for multiple + network devices of the same type). */ + int index; + + /** \brief Device flags. + The lowest 16 bits of this value are reserved for use by libppp. You are + free to use the other 16 bits as you see fit in your driver. */ + uint32_t flags; + + /** \brief Private, device-specific data. + This can be used for whatever the driver deems fit. The PPP code won't + touch this data at all. Set to NULL if you don't need anything here. */ + void *privdata; + + /** \brief Attempt to detect the device. + \param self The network device in question. + \return 0 on success, <0 on failure. + */ + int (*detect)(struct ppp_device *self); + + /** \brief Initialize the device. + \param self The network device in question. + \return 0 on success, <0 on failure. + */ + int (*init)(struct ppp_device *self); + + /** \brief Shutdown the device. + \param self The network device in question. + \return 0 on success, <0 on failure. + */ + int (*shutdown)(struct ppp_device *self); + + /** \brief Transmit data on the device. + + This function will be called periodically to transmit data on the + underlying device. The data passed in may not necessarily be a whole + packet (check the flags to see what's being passed in). + + \param self The network device in question. + \param data The data to transmit. + \param len The length of the data to transmit in bytes. + \param flags Flags to describe what data is being sent in. + \return 0 on success, <0 on failure. + */ + int (*tx)(struct ppp_device *self, const uint8_t *data, size_t len, + uint32_t flags); + + /** \brief Poll for queued receive data. + + This function will be called periodically by a thread to check the + device for any new incoming data. + + \param self The network device in question. + \return A pointer to the received data on success. NULL on + failure or if no data is waiting. + */ + const uint8_t *(*rx)(struct ppp_device *self, ssize_t *out_len); +} ppp_device_t; + +/** \brief End of packet flag. */ +#define PPP_TX_END_OF_PKT 0x00000001 + +/** \brief PPP Protocol structure. + + Each protocol that the PPP library can handle must have one of these + registered. All protocols should be registered BEFORE attempting to actually + establish a PPP session to ensure that each protocol can be used in the + setup of the connection as needed. + + \headerfile ppp/ppp.h +*/ +typedef struct ppp_proto { + /** \brief Protocol list entry (not a function!). */ + TAILQ_ENTRY(ppp_proto) entry; + + /** \brief Protocol name ("lcp", "pap", etc). */ + const char *name; + + /** \brief Protocol code. */ + uint16_t code; + + /** \brief Private data (if any). */ + void *privdata; + + /** \brief Initialization function. + + \param self The protocol structure for this protocol. + \return 0 on success, <0 on failure. + \note Set to NULL if this is not needed in the protocol. + */ + int (*init)(struct ppp_proto *self); + + /** \brief Shutdown function. + + This function should perform any protocol-specific shutdown actions and + unregister the protocol from the PPP protocol list. + + \param self The protocol structure for this protocol. + \return 0 on success, <0 on failure. + */ + int (*shutdown)(struct ppp_proto *self); + + /** \brief Protocol packet input function. + + This function will be called for each packet delivered to the specified + protocol. + + \param self The protocol structure for this protocol. + \param pkt The packet being delivered. + \param len The length of the packet in bytes. + \return 0 on success, <0 on failure. + */ + int (*input)(struct ppp_proto *self, const uint8_t *buf, size_t len); + + /** \brief Notify the protocol of a PPP phase change. + + This function will be called by the PPP automaton any time that a phase + change is initiated. This is often used for starting up a protocol when + appropriate to do so (for instance, LCP uses this to begin negotiating + configuration options with the peer when the establish phase is entered + by the automaton). + + \param self The protocol structure for this protocol. + \param oldp The old phase (the one the automaton is leaving). + \param newp The new phase. + \see ppp_phases + */ + void (*enter_phase)(struct ppp_proto *self, int oldp, int newp); + + /** \brief Check timeouts for resending packets. + + This function will be called periodically to allow the protocol to check + any resend timers that it might have responsibility for. + + \param self The protocol structure for this protocol. + \param tm The current system time for checking timeouts + against (in milliseconds since system startup). + */ + void (*check_timeouts)(struct ppp_proto *self, uint64_t tm); +} ppp_protocol_t; + +/** \brief Static initializer for protocol list entry. */ +#define PPP_PROTO_ENTRY_INIT { NULL, NULL } + +/** \defgroup ppp_phases PPP automaton phases + + This list defines the phases of the PPP automaton, as described in Section + 3.2 of RFC 1661. + + @{ +*/ +#define PPP_PHASE_DEAD 0x01 /**< \brief Pre-connection. */ +#define PPP_PHASE_ESTABLISH 0x02 /**< \brief Establishing connection. */ +#define PPP_PHASE_AUTHENTICATE 0x03 /**< \brief Authentication to peer. */ +#define PPP_PHASE_NETWORK 0x04 /**< \brief Established and working. */ +#define PPP_PHASE_TERMINATE 0x05 /**< \brief Tearing down the link. */ +/** @} */ + +/** \brief Set the device used to do PPP communications. + + This function sets the device that further communications over a + point-to-point link will take place over. The device need not be ready to + communicate immediately upon calling this function. + + Unless you are adding support for a new device, you will probably never have + to call this function. For instance, if you want to use the Dreamcast serial + port to establish a link, the ppp_scif_init() function will call this for + you. + + \param dev The device to use for communication. + \return 0 on success, <0 on failure. + + \note Calling this function after establishing a PPP link will + fail. +*/ +int ppp_set_device(ppp_device_t *dev); + +/** \brief Set the login credentials used to authenticate to the peer. + + This function sets the login credentials that will be used to authenticate + to the peer, if the peer requests authentication. The specifics of how the + authentication takes place depends on what options are configured when + establishing the link. + + \param username The username to authenticate as. + \param password The password to use to authenticate. + \return 0 on success, <0 on failure. + + \note Calling this function after establishing a PPP link will + fail. +*/ +int ppp_set_login(const char *username, const char *password); + +/** \brief Send a packet on the PPP link. + + This function sends a single packet to the peer on the PPP link. Generally, + you should not use this function directly, but rather use the facilities + provided by KOS' network stack. + + \param data The packet to send. + \param len The length of the packet, in bytes. + \param proto The PPP protocol number for the packet. + \return 0 on success, <0 on failure. +*/ +int ppp_send(const uint8_t *data, size_t len, uint16_t proto); + +/** \brief Register a protocol with the PPP stack. + + This function adds a new protocol to the PPP stack, allowing the stack to + communicate packets for the given protocol across the link. Generally, you + should not have any reason to call this function, as the library includes + a set of protocols to do normal communications. + + \param hnd A protocol handler structure. + \return 0 on success, <0 on failure. +*/ +int ppp_add_protocol(ppp_protocol_t *hnd); + +/** \brief Unregister a protocol from the PPP stack. + + This function removes protocol from the PPP stack. This should be done at + shutdown time of any protocols added with ppp_add_protocol(). + + \param hnd A protocol handler structure. + \return 0 on success, <0 on failure. +*/ +int ppp_del_protocol(ppp_protocol_t *hnd); + +/** \brief Send a Protocol Reject packet on the link. + + This function sends a LCP protocol reject packet on the link for the + specified packet. Generally, you should not have to call this function, as + the library will handle doing so internally. + + \param proto The PPP protocol number of the invalid packet. + \param pkt The packet itself. + \param len The length of the packet, in bytes. + \return 0 on success, <0 on failure. +*/ +int ppp_lcp_send_proto_reject(uint16_t proto, const uint8_t *pkt, size_t len); + +/** \defgroup ppp_flags PPP link configuration flags + + This list defines the flags we can negotiate during link establishment. + + @{ +*/ +#define PPP_FLAG_AUTH_PAP 0x00000001 /**< \brief PAP authentication */ +#define PPP_FLAG_AUTH_CHAP 0x00000002 /**< \brief CHAP authentication */ +#define PPP_FLAG_PCOMP 0x00000004 /**< \brief Protocol compression */ +#define PPP_FLAG_ACCOMP 0x00000008 /**< \brief Addr/ctrl compression */ +#define PPP_FLAG_MAGIC_NUMBER 0x00000010 /**< \brief Use magic numbers */ +#define PPP_FLAG_WANT_MRU 0x00000020 /**< \brief Specify MRU */ +#define PPP_FLAG_NO_ACCM 0x00000040 /**< \brief No ctl character map */ +/** @} */ + +/** \brief Get the flags set for our side of the link. + + This function retrieves the connection flags set for our side of the PPP + link. Before link establishment, this indicates the flags we would like to + establish on the link and after establishment it represents the flags that + were actually negotiated during link establishment. + + \return Bitwise OR of \ref ppp_flags. +*/ +uint32_t ppp_get_flags(void); + +/** \brief Get the flags set for the peer's side of the link. + + This function retrieves the connection flags set for the other side of the + PPP link. This value is only valid after link establishment. + + \return Bitwise OR of \ref ppp_flags. +*/ +uint32_t ppp_get_peer_flags(void); + +/** \brief Get the flags set for our side of the link. + + This function retrieves the connection flags set for our side of the PPP + link. Before link establishment, this indicates the flags we would like to + establish on the link and after establishment it represents the flags that + were actually negotiated during link establishment. + + \return Bitwise OR of \ref ppp_flags. +*/ +void ppp_set_flags(uint32_t flags); + +/** \brief Establish a point-to-point link across a previously set-up device. + + This function establishes a point-to-point link to the peer across a device + that was previously set up with ppp_set_device(). Before calling this + function, the device must be ready to communicate with the peer. That is to + say, any handshaking needed to establish the underlying hardware link must + have already completed. + + \return 0 on success, <0 on failure. + + \note This function will block until the link is established. +*/ +int ppp_connect(void); + +/** \brief Initialize the Dreamcast serial port for a PPP link. + + This function sets up the Dreamcast serial port to act as a communications + link for a point-to-point connection. This can be used in conjunction with a + coder's cable (or similar) to connect the Dreamcast to a PC and the internet + if the target system is set up properly. + + \param bps The speed to initialize the serial port at. + \return 0 on success, <0 on failure. +*/ +int ppp_scif_init(int bps); + +/** \brief Initialize the PPP library. + + This function initializes the PPP library, preparing internal structures for + use and initializing the PPP protocols needed for normal IP communications. + + \return 0 on success, <0 on failure. +*/ +int ppp_init(void); + +/** \brief Shut down the PPP library. + + This function cleans up the PPP library, shutting down any connections and + deinitializing any protocols that have bene registered previously. + + \return 0 on success, <0 on failure. +*/ +int ppp_shutdown(void); + +__END_DECLS +#endif /* !__PPP_PPP_H */ diff --git a/addons/libppp/Makefile b/addons/libppp/Makefile new file mode 100644 index 0000000..04d897e --- /dev/null +++ b/addons/libppp/Makefile @@ -0,0 +1,13 @@ +# libppp Makefile +# + +TARGET = libppp.a +OBJS = ppp.o lcp.o pap.o ipcp.o + +# Make sure everything compiles nice and cleanly (or not at all). +KOS_CFLAGS += -W -pedantic -Werror -std=c99 -I$(KOS_BASE)/kernel/net + +# Uncomment the line below to enable all manner of debugging output. +KOS_CFLAGS += -DPPP_DEBUG + +include $(KOS_BASE)/addons/Makefile.prefab diff --git a/addons/libppp/fcs.h b/addons/libppp/fcs.h new file mode 100644 index 0000000..bfbc148 --- /dev/null +++ b/addons/libppp/fcs.h @@ -0,0 +1,50 @@ +/* KallistiOS ##version## + + libppp/fcs.h + Copyright (C) 2007, 2014 Lawrence Sebald +*/ + +#ifndef __LOCAL_PPP_FCS_H +#define __LOCAL_PPP_FCS_H + +#include <stdint.h> + +#define INITIAL_FCS 0xFFFF +#define FINAL_FCS 0xF0B8 + +static uint16_t fcstab[256] = { + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +#endif /* !__LOCAL_PPP_FCS_H */ diff --git a/addons/libppp/ipcp.c b/addons/libppp/ipcp.c new file mode 100644 index 0000000..5d1d38a --- /dev/null +++ b/addons/libppp/ipcp.c @@ -0,0 +1,711 @@ +/* KallistiOS ##version## + + libppp/ipcp.c + Copyright (C) 2007, 2014 Lawrence Sebald +*/ + +#include <stdio.h> +#include <stdint.h> +#include <string.h> + +#include <ppp/ppp.h> + +#include <kos/net.h> + +#include <arch/timer.h> ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-06-04 21:35:28
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 38a612d447f0f2b5e533dd2cbb75d9f489652f7e (commit) via 07ccde0326c670cedaf30b3394f1fff9809f3951 (commit) from 0103890eb416dabf173909cc14a356fdf2927218 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 38a612d447f0f2b5e533dd2cbb75d9f489652f7e Author: Lawrence Sebald <ljs...@us...> Date: Wed Jun 4 17:33:01 2014 -0400 Add some support code for network devices that might not use ethernet to net_ipv4 and net_ipv6. commit 07ccde0326c670cedaf30b3394f1fff9809f3951 Author: Lawrence Sebald <ljs...@us...> Date: Wed Jun 4 17:32:10 2014 -0400 Update the environ.sh.sample to match what dc-chain assumes. ----------------------------------------------------------------------- Summary of changes: doc/environ.sh.sample | 4 ++-- include/kos/net.h | 2 +- kernel/net/net_ipv4.c | 11 +++++++++++ kernel/net/net_ipv6.c | 10 ++++++++++ 4 files changed, 24 insertions(+), 3 deletions(-) diff --git a/doc/environ.sh.sample b/doc/environ.sh.sample index 891288b..357aa12 100644 --- a/doc/environ.sh.sample +++ b/doc/environ.sh.sample @@ -20,7 +20,7 @@ export KOS_SUBARCH="pristine" # export KOS_SUBARCH="rte" # PS2 # KOS main base path -export KOS_BASE="/usr/local/home/bard/prj/svn/kos" +export KOS_BASE="/opt/toolchains/dc/kos" # Make utility export KOS_MAKE="make" @@ -55,7 +55,7 @@ export DC_ARM_BASE="/opt/toolchains/dc/arm-eabi" export DC_ARM_PREFIX="arm-eabi" # Expand PATH (comment out if you don't want this done here) -export PATH="${PATH}:${KOS_CC_BASE}/bin:/usr/local/dc/bin" +export PATH="${PATH}:${KOS_CC_BASE}/bin:/opt/toolchains/dc/bin" # Manually add our second addons tree export KOS_INC_PATHS="-I${KOS_BASE}/../kos-ports/include" diff --git a/include/kos/net.h b/include/kos/net.h index ae41958..8924671 100644 --- a/include/kos/net.h +++ b/include/kos/net.h @@ -182,6 +182,7 @@ typedef struct knetif { #define NETIF_RUNNING 0x00000008 /**< \brief Has start() been called? */ #define NETIF_PROMISC 0x00010000 /**< \brief Promiscuous mode */ #define NETIF_NEEDSPOLL 0x01000000 /**< \brief Needs to be polled for input */ +#define NETIF_NOETH 0x10000000 /**< \brief Does not use ethernet */ /** @} */ /* Return types for if_tx */ @@ -762,4 +763,3 @@ void net_shutdown(void); __END_DECLS #endif /* __KOS_NET_H */ - diff --git a/kernel/net/net_ipv4.c b/kernel/net/net_ipv4.c index 204cc58..4e12561 100644 --- a/kernel/net/net_ipv4.c +++ b/kernel/net/net_ipv4.c @@ -121,6 +121,17 @@ int net_ipv4_send_packet(netif_t *net, ip_hdr_t *hdr, const uint8 *data, return 0; } + else if(net->flags & NETIF_NOETH) { + /* Put the IP header / data into our packet */ + memcpy(pkt, hdr, 4 * (hdr->version_ihl & 0x0f)); + memcpy(pkt + 4 * (hdr->version_ihl & 0x0f), data, size); + + ++ipv4_stats.pkt_sent; + + /* Send it away */ + return net->if_tx(net, pkt, 4 * (hdr->version_ihl & 0x0f) + size, + NETIF_BLOCK); + } /* Are we sending a broadcast packet? */ if(hdr->dest == 0xFFFFFFFF || is_broadcast(dest_ip, net->broadcast)) { diff --git a/kernel/net/net_ipv6.c b/kernel/net/net_ipv6.c index 2070f86..266ff0d 100644 --- a/kernel/net/net_ipv6.c +++ b/kernel/net/net_ipv6.c @@ -83,6 +83,16 @@ int net_ipv6_send_packet(netif_t *net, ipv6_hdr_t *hdr, const uint8 *data, net_ipv6_input(NULL, pkt, sizeof(ipv6_hdr_t) + data_size, NULL); return 0; } + else if(net->flags & NETIF_NOETH) { + memcpy(pkt, hdr, sizeof(ipv6_hdr_t)); + memcpy(pkt + sizeof(ipv6_hdr_t), data, data_size); + + ++ipv6_stats.pkt_sent; + + /* Send the packet away */ + return net->if_tx(net, pkt, sizeof(ipv6_hdr_t) + data_size, + NETIF_BLOCK); + } else if(IN6_IS_ADDR_MULTICAST(&hdr->dst_addr)) { dst_mac[0] = dst_mac[1] = 0x33; dst_mac[2] = hdr->dst_addr.__s6_addr.__s6_addr8[12]; hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-05-17 21:24:42
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 0103890eb416dabf173909cc14a356fdf2927218 (commit) from 03e4620053aaa3f22ca37023b98991a4fdc04d4b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0103890eb416dabf173909cc14a356fdf2927218 Author: Lawrence Sebald <ljs...@us...> Date: Sat May 17 17:24:10 2014 -0400 Fix the make_authors.awk script to handle quotes in names. ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/kernel/make_authors.awk | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diff --git a/kernel/arch/dreamcast/kernel/make_authors.awk b/kernel/arch/dreamcast/kernel/make_authors.awk index 8306288..4ee8981 100644 --- a/kernel/arch/dreamcast/kernel/make_authors.awk +++ b/kernel/arch/dreamcast/kernel/make_authors.awk @@ -1,7 +1,7 @@ # KallistiOS ##version## # # arch/dreamcast/kernel/make_authors.awk -# Copyright (C) 2013 Lawrence Sebald +# Copyright (C) 2013, 2014 Lawrence Sebald # This script processes the AUTHORS file in the root directory of the source # distribution to create the authors.h file that is needed in banner.c. This @@ -28,6 +28,7 @@ BEGIN { exit; } else if(phase == 2 && $0 != "") { + gsub(/"/, "\\\"", $1) print "\"Copyright (C)" $2, $1 "\\n\""; } } hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-05-17 03:52:16
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 03e4620053aaa3f22ca37023b98991a4fdc04d4b (commit) via af627976b251f1faa22e7d09bf93d11d701bfd7f (commit) via 5114c558fbe48c5387d8b61a67fee0be6dc671e0 (commit) via bcf99a6973f3a91ac87c377346ff9e0f0b5fecd5 (commit) via 9ddb4d0b70bd1df79944410f397622329e5b0dfe (commit) from 030b1025feaa725200e3f1254fd49c1259664836 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 03e4620053aaa3f22ca37023b98991a4fdc04d4b Author: Lawrence Sebald <ljs...@us...> Date: Fri May 16 23:51:42 2014 -0400 Add a few more things to the .gitignore. commit af627976b251f1faa22e7d09bf93d11d701bfd7f Author: Lawrence Sebald <ljs...@us...> Date: Fri May 16 23:50:07 2014 -0400 Add scramble to the utils Makefile. commit 5114c558fbe48c5387d8b61a67fee0be6dc671e0 Author: Lawrence Sebald <ljs...@us...> Date: Fri May 16 23:48:45 2014 -0400 Add Marcus Comstedt's 1ST_READ.BIN scrambler to the utils directory. commit bcf99a6973f3a91ac87c377346ff9e0f0b5fecd5 Author: Lawrence Sebald <ljs...@us...> Date: Fri May 16 23:43:56 2014 -0400 Add g1ata to the examples Makefile. commit 9ddb4d0b70bd1df79944410f397622329e5b0dfe Author: Lawrence Sebald <ljs...@us...> Date: Fri May 16 23:42:50 2014 -0400 Add a bunch of new/useful matrix/vector math macros. Thanks to Josh "PH3NOM" Pearson for these. ----------------------------------------------------------------------- Summary of changes: .gitignore | 4 + AUTHORS | 1 + doc/CHANGELOG | 7 +- doc/README.KOS | 10 +- examples/dreamcast/Makefile | 2 +- kernel/arch/dreamcast/include/dc/matrix.h | 227 ++++++++++++++++++++++++- kernel/arch/dreamcast/include/dc/vec3f.h | 180 ++++++++++++++++++++ utils/Makefile | 2 +- utils/scramble/Makefile | 10 + utils/scramble/README | 2 + utils/scramble/scramble.c | 260 +++++++++++++++++++++++++++++ 11 files changed, 687 insertions(+), 18 deletions(-) create mode 100644 kernel/arch/dreamcast/include/dc/vec3f.h create mode 100644 utils/scramble/Makefile create mode 100644 utils/scramble/README create mode 100644 utils/scramble/scramble.c diff --git a/.gitignore b/.gitignore index 979f5c3..5a2d891 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,7 @@ examples/dreamcast/pvr/texture_render/texture_render.bin utils/dc-chain/logs utils/dc-chain/*.tar.bz2 utils/dc-chain/*.tar.gz +utils/dc-chain/binutils-* +utils/dc-chain/gcc-* +utils/dc-chain/newlib-* +utils/scramble/scramble diff --git a/AUTHORS b/AUTHORS index dcf916d..ee8140c 100644 --- a/AUTHORS +++ b/AUTHORS @@ -38,6 +38,7 @@ Vincent Penne: 2004 Roger Cattermole: 2002 Paul Boese: 2002 Brian Paul: 1999, 2000, 2001 +Josh "PH3NOM" Pearson: 2013, 2014 Files with Specific licenses: ----------------------------- diff --git a/doc/CHANGELOG b/doc/CHANGELOG index 23ab722..cc449f3 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -1,6 +1,8 @@ Platform independent changes are marked with '***', otherwise the -applicable platform is listed. If someone besides me found the bug or -suggested the fix, I'll put their name in [ ]. +applicable platform is listed. The name/initials of the person who +is responsible for the change are listed in [square brackets] for most +versions (where they are missing from early versions, assume that they +should be attributed to Dan Potter). KallistiOS version 2.0.1 ----------------------------------------------- - *** Cleaned up generated stubs files on a make clean [Lawrence Sebald = LS] @@ -37,6 +39,7 @@ KallistiOS version 2.0.1 ----------------------------------------------- - DC Fixed potential race conditions between the cdrom code and g1ata [LS] - DC Fixed full sector reading of non-data CDs (thanks to SWAT for pointing out that it needed fixing) [LS] +- DC Added many new matrix/vector math-related macros [Josh Pearson = JP] KallistiOS version 2.0.0 ----------------------------------------------- - DC Broadband Adapter driver fixes [Dan Potter == DP] diff --git a/doc/README.KOS b/doc/README.KOS index ab4e99d..257c0d1 100644 --- a/doc/README.KOS +++ b/doc/README.KOS @@ -15,9 +15,9 @@ the header: * KOS License (README.KOS) for more details. * * You should have received a copy of the KOS License along with this -* program; if not, please visit Cryptic Allusion DCDev at: +* program; if not, please visit Cryptic Allusion Game Dev at: * -* http://dcdev.allusion.net/ +* http://gamedev.allusion.net/ * The text of that license follows. In layman's terms, all it really @@ -28,9 +28,10 @@ documentation is ok) and there is no warranty. Dan Potter All of the documentation and software included in the KallistiOS Releases -is copyrighted (C) 2000-2013 by Dan Potter and others (as noted in each file). +is copyrighted (C) 2000-2014 by Dan Potter, Lawrence Sebald, and others (as +noted in each file). -Copyright (C) 1997-2013 KallistiOS Contributors. All rights reserved. +Copyright (C) 1997-2014 KallistiOS Contributors. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -55,4 +56,3 @@ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - diff --git a/examples/dreamcast/Makefile b/examples/dreamcast/Makefile index dbecb4d..020b437 100644 --- a/examples/dreamcast/Makefile +++ b/examples/dreamcast/Makefile @@ -5,7 +5,7 @@ # DIRS = 2ndmix basic libdream kgl hello sound png network vmu conio pvr video \ - lua parallax modem dreameye sd + lua parallax modem dreameye sd g1ata ifdef KOS_CCPLUS DIRS += cpp tsunami endif diff --git a/kernel/arch/dreamcast/include/dc/matrix.h b/kernel/arch/dreamcast/include/dc/matrix.h index 5da69ba..4abba47 100644 --- a/kernel/arch/dreamcast/include/dc/matrix.h +++ b/kernel/arch/dreamcast/include/dc/matrix.h @@ -1,7 +1,8 @@ /* KallistiOS ##version## - matrix.h - (c)2000 Dan Potter + dc/matrix.h + Copyright (C) 2000 Dan Potter + Copyright (C) 2013, 2014 Josh "PH3NOM" Pearson */ @@ -13,6 +14,7 @@ functionality is built off of these operations. \author Dan Potter + \author Josh "PH3NOM" Pearson \see dc/matrix3d.h */ @@ -117,8 +119,8 @@ void mat_transform_sq(void * input, void * output, int veccnt); This macro is an inline assembly operation to transform a single vertex. It works most efficiently if the x value is in fr0, y is in fr1, z is in fr2, and w is in fr3 before using the macro. This macro is similar to - mat_trans_single(), but this one allows an input to and preserves the Z/W - value. + \ref mat_trans_single(), but this one allows an input to and preserves the + Z/W value. \param x The X coordinate to transform. \param y The Y coordinate to transform. @@ -148,8 +150,9 @@ void mat_transform_sq(void * input, void * output, int veccnt); This macro is an inline assembly operation to transform a single vertex. It works most efficiently if the x value is in fr0, y is in fr1, and z is in - fr2 before using the macro. This macro is similar to mat_trans_single(), but - this one leaves z/w instead of 1/w for the z component. + fr2 before using the macro. This macro is similar to + \ref mat_trans_single(), but this one leaves z/w instead of 1/w for the z + component. \param x The X coordinate to transform. \param y The Y coordinate to transform. @@ -177,7 +180,7 @@ void mat_transform_sq(void * input, void * output, int veccnt); This macro is an inline assembly operation to transform a single vertex. It works most efficiently if the x value is in fr0, y is in fr1, z is in fr2, and w is in fr3 before using the macro. This macro is similar to - mat_trans_single(), but this one does not do any perspective division. + \ref mat_trans_single(), but this one does not do any perspective division. \param x The X coordinate to transform. \param y The Y coordinate to transform. @@ -196,8 +199,214 @@ void mat_transform_sq(void * input, void * output, int veccnt); x = __x; y = __y; z = __z; w = __w; \ } +/** \brief Macro to transform a single 3d vertex coordinate by the internal + matrix with no perspective division. -__END_DECLS + This macro is an inline assembly operation to transform a 3 float vertex + coordinate. It works most efficiently if the x value is in fr12, y is in + fr13, and z is in fr14 before using the macro. This macro is similar to + \ref mat_trans_nodiv(), but this one sets the W component to 1 for use with + a 3d vector. + + \param x The X coordinate to transform. + \param y The Y coordinate to transform. + \param z The Z coordinate to transform. +*/ +#define mat_trans_single3_nodiv(x, y, z) { \ + register float __x __asm__("fr12") = (x); \ + register float __y __asm__("fr13") = (y); \ + register float __z __asm__("fr14") = (z); \ + __asm__ __volatile__( \ + "fldi1 fr15\n" \ + "ftrv xmtrx, fv12\n" \ + : "=f" (__x), "=f" (__y), "=f" (__z) \ + : "0" (__x), "1" (__y), "2" (__z) ); \ + x = __x; y = __y; z = __z; \ + } + +/** \brief Macro to transform a single 3d vertex coordinate by the internal + matrix with perspective division. + + This macro is an inline assembly operation to transform a 3 float vertex + coordinate. It works most efficiently if the x value is in fr12, y is in + fr13, and z is in fr14 before using the macro. This macro is similar to + \ref mat_trans_single(), but this one does not modify the input operands, + instead storing the transformed vector to the output operands. + + \param x The X coordinate to input transform. + \param y The Y coordinate to input transform. + \param z The Z coordinate to input transform. + \param x2 The X coordinate to output transform. + \param y2 The Y coordinate to output transform. + \param z2 The Z coordinate to output transform. +*/ +#define mat_trans_single3_nomod(x, y, z, x2, y2, z2) { \ + register float __x __asm__("fr12") = (x); \ + register float __y __asm__("fr13") = (y); \ + register float __z __asm__("fr14") = (z); \ + __asm__ __volatile__( \ + "fldi1 fr15\n" \ + "ftrv xmtrx, fv12\n" \ + "fldi1 fr14\n" \ + "fdiv fr15, fr14\n" \ + "fmul fr14, fr12\n" \ + "fmul fr14, fr13\n" \ + : "=f" (__x), "=f" (__y), "=f" (__z) \ + : "0" (__x), "1" (__y), "2" (__z) \ + : "fr15" ); \ + x2 = __x; y2 = __y; z2 = __z; \ + } + +/** \brief Macro to transform a single 3d vertex coordinate by the internal + matrix. + + This macro is an inline assembly operation to transform a 3 float vertex + coordinate. It works most efficiently if the x value is in fr12, y is in + fr13, and z is in fr14 before using the macro. This macro is similar to + \ref mat_trans_single3_nodiv(), but this one does not modify the input + operands, instead storing the transformed vector to the output operands. + + \param x The X coordinate to input transform. + \param y The Y coordinate to input transform. + \param z The Z coordinate to input transform. + \param x2 The X coordinate to output transform. + \param y2 The Y coordinate to output transform. + \param z2 The Z coordinate to output transform. +*/ +#define mat_trans_single3_nodiv_nomod(x, y, z, x2, y2, z2) { \ + register float __x __asm__("fr12") = (x); \ + register float __y __asm__("fr13") = (y); \ + register float __z __asm__("fr14") = (z); \ + __asm__ __volatile__( \ + "fldi1 fr15\n" \ + "ftrv xmtrx, fv12\n" \ + : "=f" (__x), "=f" (__y), "=f" (__z) \ + : "0" (__x), "1" (__y), "2" (__z) ); \ + x2 = __x; y2 = __y; z2 = __z; \ + } + +/** \brief Macro to transform a single 3d vertex coordinate by the internal + matrix. + + This macro is an inline assembly operation to transform a 3 float vertex + coordinate. It works most efficiently if the x value is in fr12, y is in + fr13, and z is in fr14 before using the macro. This macro is similar to + \ref mat_trans_single3_nodiv(), but this one stores the W component of + transform for later perspective divide. + + \param x The X coordinate to transform. + \param y The Y coordinate to transform. + \param z The Z coordinate to transform. + \param w The W coordinate output of transform. +*/ +#define mat_trans_single3_nodivw(x, y, z, w) { \ + register float __x __asm__("fr12") = (x); \ + register float __y __asm__("fr13") = (y); \ + register float __z __asm__("fr14") = (z); \ + register float __w __asm__("fr15"); \ + __asm__ __volatile__( \ + "fldi1 fr15\n" \ + "ftrv xmtrx, fv12\n" \ + : "=f" (__x), "=f" (__y), "=f" (__z) \ + : "0" (__x), "1" (__y), "2" (__z) ); \ + x = __x; y = __y; z = __z; w = __w; \ + } + +/** \brief Macro to transform a single 3d vertex coordinate by the internal + matrix both with and without perspective division. + + This macro is an inline assembly operation to transform a 3 float vertex + coordinate. It works most efficiently if the x value is in fr0, y is in fr1, + and z is in fr2 before using the macro. This macro is similar to + \ref mat_trans_single(), but this one is used for transforming input vertex + with and without perspective division. + + \param x The X coordinate to transform without perspective + divide. + \param y The Y coordinate to transform without perspective + divide. + \param z The Z coordinate to transform without perspective + divide. + \param xd The X coordinate to output transform with + perspective divide. + \param yd The Y coordinate to output transform with + perspective divide. + \param zd The Z coordinate to output transform with + perspective divide. +*/ +#define mat_trans_single3_nodiv_div(x, y, z, xd, yd, zd) { \ + register float __x __asm__("fr0") = (x); \ + register float __y __asm__("fr1") = (y); \ + register float __z __asm__("fr2") = (z); \ + register float __xd __asm__("fr4"); \ + register float __yd __asm__("fr5"); \ + register float __zd __asm__("fr6"); \ + __asm__ __volatile__( \ + "fldi1 fr3\n" \ + "ftrv xmtrx, fv0\n" \ + "fmov fr0, fr4\n" \ + "fmov fr1, fr5\n" \ + "fmov fr3, fr7\n" \ + "fldi1 fr6\n" \ + "fdiv fr7, fr6\n" \ + "fmul fr6, fr4\n" \ + "fmul fr6, fr5\n" \ + : "=f" (__x), "=f" (__y), "=f" (__z) \ + : "0" (__x), "1" (__y), "2" (__z) ); \ + x = __x; y = __y; z = __z; xd = __xd; yd = __yd; zd = __zd; \ + } + +/** \brief Macro to transform a single vertex normal by the internal matrix. + + This macro is an inline assembly operation to transform a 3 float vertex + normal. It works most efficiently if the x value is in fr8, y is in fr9, + and z is in fr10 before using the macro. This macro is similar to + \ref mat_trans_nodiv(), but this one sets the W component to 0 in order to + transform a vertex normal, rather than 1 for a vertex position. -#endif /* __DC_MATRIX_H */ + \param x The X normal to transform. + \param y The Y normal to transform. + \param z The Z normal to transform. +*/ +#define mat_trans_normal3(x, y, z) { \ + register float __x __asm__("fr8") = (x); \ + register float __y __asm__("fr9") = (y); \ + register float __z __asm__("fr10") = (z); \ + __asm__ __volatile__( \ + "fldi0 fr11\n" \ + "ftrv xmtrx, fv8\n" \ + : "=f" (__x), "=f" (__y), "=f" (__z) \ + : "0" (__x), "1" (__y), "2" (__z) ); \ + x = __x; y = __y; z = __z; \ + } + +/** \brief Macro to transform a single vertex normal by the internal matrix. + + This macro is an inline assembly operation to transform a 3 float vertex + normal. It works most efficiently if the x value is in fr8, y is in fr9, + and z is in fr10 before using the macro. This macro is similar to + \ref mat_trans_normal3(), but this one does not modify the input operands, + instead storing the transformed vector to the output operands. + + \param x The X normal to input transform. + \param y The Y normal to input transform. + \param z The Z normal to input transform. + \param x2 The X normal to output transform. + \param y2 The Y normal to output transform. + \param z2 The Z normal to output transform. +*/ +#define mat_trans_normal3_nomod(x, y, z, x2, y2, z2) { \ + register float __x __asm__("fr8") = (x); \ + register float __y __asm__("fr9") = (y); \ + register float __z __asm__("fr10") = (z); \ + __asm__ __volatile__( \ + "fldi0 fr11\n" \ + "ftrv xmtrx, fv8\n" \ + : "=f" (__x), "=f" (__y), "=f" (__z) \ + : "0" (__x), "1" (__y), "2" (__z) ); \ + x2 = __x; y2 = __y; z2 = __z; \ + } + +__END_DECLS +#endif /* !__DC_MATRIX_H */ diff --git a/kernel/arch/dreamcast/include/dc/vec3f.h b/kernel/arch/dreamcast/include/dc/vec3f.h new file mode 100644 index 0000000..dc84b21 --- /dev/null +++ b/kernel/arch/dreamcast/include/dc/vec3f.h @@ -0,0 +1,180 @@ +/* KallistiOS ##version## + + dc/vec3f.h + Copyright (C) 2013, 2014 Josh "PH3NOM" Pearson + +*/ + +/** \file dc/vec3f.h + \brief Basic matrix operations. + + This file contains various basic vector math functionality for using the + SH4's vector instructions. Higher level functionality in KGL is built off + of these. + + \author Josh "PH3NOM" Pearson + \see dc/matrix.h +*/ + +#ifndef __DC_VEC3F_H +#define __DC_VEC3F_H + +#include <sys/cdefs.h> +__BEGIN_DECLS + +#include <kos/vector.h> + +/** \brief Macro to return the scalar dot product of two 3d vectors. + + This macro is an inline assembly operation using the SH4's fast + (approximate) math instructions, and returns a single-precision + floating-point value. + + \param x1 The X coordinate of first vector. + \param y1 The Y coordinate of first vector. + \param z1 The Z coordinate of first vector. + \param x2 The X coordinate of second vector. + \param y2 The Y coordinate of second vector. + \param z2 The Z coordinate of second vector. + \param w The result of the calculation. +*/ +#define vec3f_dot(x1, y1, z1, x2, y2, z2, w) { \ + register float __x __asm__("fr0") = (x1); \ + register float __y __asm__("fr1") = (y1); \ + register float __z __asm__("fr2") = (z1); \ + register float __w __asm__("fr3"); \ + register float __a __asm__("fr4") = (x2); \ + register float __b __asm__("fr5") = (y2); \ + register float __c __asm__("fr6") = (z2); \ + register float __d __asm__("fr7"); \ + __asm__ __volatile__( \ + "fldi0 fr3\n" \ + "fldi0 fr7\n" \ + "fipr fv4,fv0" \ + : "+f" (__w) \ + : "f" (__x), "f" (__y), "f" (__z), "f" (__w), \ + "f" (__a), "f" (__b), "f" (__c), "f" (__d) \ + ); \ + w = __w; \ + } + +/** \brief Macro to return scalar Euclidean length of a 3d vector. + + This macro is an inline assembly operation using the SH4's fast + (approximate) math instructions, and returns a single-precision + floating-point value. + + \param x The X coordinate of vector. + \param y The Y coordinate of vector. + \param z The Z coordinate of vector. + \param w The result of the calculation. +*/ +#define vec3f_length(x, y, z, w) { \ + register float __x __asm__("fr0") = (x); \ + register float __y __asm__("fr1") = (y); \ + register float __z __asm__("fr2") = (z); \ + register float __w __asm__("fr3"); \ + __asm__ __volatile__( \ + "fldi0 fr3\n" \ + "fipr fv0,fv0\n" \ + "fsqrt fr3\n" \ + : "+f" (__w) \ + : "f" (__x), "f" (__y), "f" (__z), "f" (__w) \ + ); \ + w = __w; \ + } + +/** \brief Macro to return the Euclidean distance between two 3d vectors. + + This macro is an inline assembly operation using the SH4's fast + (approximate) math instructions, and returns a single-precision + floating-point value. + + \param x1 The X coordinate of first vector. + \param y1 The Y coordinate of first vector. + \param z1 The Z coordinate of first vector. + \param x2 The X coordinate of second vector. + \param y2 The Y coordinate of second vector. + \param z2 The Z coordinate of second vector. + \param w The result of the calculation. +*/ +#define vec3f_distance(x1, y1, z1, x2, y2, z2, w) { \ + register float __x __asm__("fr0") = (x2-x1); \ + register float __y __asm__("fr1") = (y2-y1); \ + register float __z __asm__("fr2") = (z2-z1); \ + register float __w __asm__("fr3"); \ + __asm__ __volatile__( \ + "fldi0 fr3\n" \ + "fipr fv0,fv0\n" \ + "fsqrt fr3\n" \ + : "+f" (__w) \ + : "f" (__x), "f" (__y), "f" (__z), "f" (__w) \ + ); \ + w = __w; \ + } + +/** \brief Macro to return the normalized version of a vector. + + This macro is an inline assembly operation using the SH4's fast + (approximate) math instructions to calculate a vector that is in the same + direction as the input vector but with a Euclidean length of one. The input + vector is modified by the operation as the resulting values. + + \param x The X coordinate of vector. ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-05-17 01:53:20
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A serial program loader for the Dreamcast.". The branch, master has been updated via 697d5d41eb701345f9d1f9f8c274f338a14c356d (commit) from 5d88a59d62033a6dcffce8221370675d3601676b (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 697d5d41eb701345f9d1f9f8c274f338a14c356d Author: Lawrence Sebald <ljs...@us...> Date: Fri May 16 21:53:01 2014 -0400 Fix |darc|'s broken cable bug in dcload-serial. ----------------------------------------------------------------------- Summary of changes: target-src/dcload/video.s | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-) diff --git a/target-src/dcload/video.s b/target-src/dcload/video.s index 8715844..8ba049d 100644 --- a/target-src/dcload/video.s +++ b/target-src/dcload/video.s @@ -275,11 +275,13 @@ nonlace: ! Select RGB/CVBS mov.l cvbsbase,r1 - rotr r4 - bf/s rgbmode - mov #0,r0 - mov #3,r0 -rgbmode: + mov r4,r0 + and #3,r0 + !rotr r4 + !bf/s rgbmode + !mov #0,r0 + !mov #3,r0 +!rgbmode: shll8 r0 mov.l r0,@r1 hooks/post-receive -- A serial program loader for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-05-16 22:39:23
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "An ethernet program loader for the Dreamcast.". The branch, master has been updated via c49476cae2a18c6f577f7135cc13836de04c8232 (commit) from 589baf9fd567a9b97881f1ecaf1f5989afdbef69 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c49476cae2a18c6f577f7135cc13836de04c8232 Author: Lawrence Sebald <ljs...@us...> Date: Fri May 16 18:39:00 2014 -0400 Apply |darc|'s broken cable fix to dcload-ip too. ----------------------------------------------------------------------- Summary of changes: target-src/dcload/video.s | 12 +++++++----- 1 files changed, 7 insertions(+), 5 deletions(-) diff --git a/target-src/dcload/video.s b/target-src/dcload/video.s index 787df0c..6ebb6a1 100644 --- a/target-src/dcload/video.s +++ b/target-src/dcload/video.s @@ -275,11 +275,13 @@ nonlace: ! Select RGB/CVBS mov.l cvbsbase,r1 - rotr r4 - bf/s rgbmode - mov #0,r0 - mov #3,r0 -rgbmode: + mov r4,r0 + and #3,r0 + !rotr r4 + !bf/s rgbmode + !mov #0,r0 + !mov #3,r0 +!rgbmode: shll8 r0 mov.l r0,@r1 hooks/post-receive -- An ethernet program loader for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-05-16 21:50:10
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 030b1025feaa725200e3f1254fd49c1259664836 (commit) from bdf3aa24bf8141191cb6b666a31313a2fa465242 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 030b1025feaa725200e3f1254fd49c1259664836 Author: Lawrence Sebald <ljs...@us...> Date: Fri May 16 17:47:45 2014 -0400 Fix |darc|'s broken cable bug. Basically, |darc| made a VGA cable incorrectly and found that KOS' behavior with it differed from that in the BIOS. This corrects that "problem". See http://dcemulation.org/phpBB/viewtopic.php?f=29&t=103090 for a better description of what this actually means... ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/hardware/video.c | 10 ++-------- 1 files changed, 2 insertions(+), 8 deletions(-) diff --git a/kernel/arch/dreamcast/hardware/video.c b/kernel/arch/dreamcast/hardware/video.c index b480bac..d7c6a4d 100644 --- a/kernel/arch/dreamcast/hardware/video.c +++ b/kernel/arch/dreamcast/hardware/video.c @@ -617,12 +617,8 @@ void vid_set_mode_ex(vid_mode_t *mode) { vid_flip(0); /* Set cable type */ - if(mode->cable_type & 1) { - *((vuint32*)0xa0702c00) |= 0x300; - } - else { - *((vuint32*)0xa0702c00) &= ~0x300; - } + *((vuint32*)0xa0702c00) = (*((vuint32*)0xa0702c00) & 0xfffffcff) | + ((ct & 3) << 8); /* Re-enable the display */ regs[0x3A] &= ~8; @@ -756,5 +752,3 @@ void vid_shutdown() { /* Play nice with loaders, like KOS used to do. */ vid_init(DM_640x480, PM_RGB565); } - - hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-05-11 23:35:29
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "The KallistiOS port of SDL.". The branch, master has been updated via 10b82d38e762d9e706ebbb0a0d6b43c5d51b076a (commit) from dd770d5a611fcc80d9579b651b7476b851851b3f (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 10b82d38e762d9e706ebbb0a0d6b43c5d51b076a Author: Lawrence Sebald <ljs...@us...> Date: Sun May 11 19:34:13 2014 -0400 Remove use of deprecated semaphore functions from SDL. Thanks to Indiket for pointing out that they were still in use. ----------------------------------------------------------------------- Summary of changes: base/src/thread/dc/SDL_syssem.c | 122 +++++++++++++++++++++------------------ 1 files changed, 65 insertions(+), 57 deletions(-) diff --git a/base/src/thread/dc/SDL_syssem.c b/base/src/thread/dc/SDL_syssem.c index b9bb6cd..da0ebf8 100644 --- a/base/src/thread/dc/SDL_syssem.c +++ b/base/src/thread/dc/SDL_syssem.c @@ -39,42 +39,42 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) { - SDL_SetError("SDL not configured with thread support"); - return (SDL_sem *)0; + SDL_SetError("SDL not configured with thread support"); + return (SDL_sem *)0; } void SDL_DestroySemaphore(SDL_sem *sem) { - return; + return; } int SDL_SemTryWait(SDL_sem *sem) { - SDL_SetError("SDL not configured with thread support"); - return -1; + SDL_SetError("SDL not configured with thread support"); + return -1; } int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) { - SDL_SetError("SDL not configured with thread support"); - return -1; + SDL_SetError("SDL not configured with thread support"); + return -1; } int SDL_SemWait(SDL_sem *sem) { - SDL_SetError("SDL not configured with thread support"); - return -1; + SDL_SetError("SDL not configured with thread support"); + return -1; } Uint32 SDL_SemValue(SDL_sem *sem) { - return 0; + return 0; } int SDL_SemPost(SDL_sem *sem) { - SDL_SetError("SDL not configured with thread support"); - return -1; + SDL_SetError("SDL not configured with thread support"); + return -1; } #else @@ -83,12 +83,19 @@ int SDL_SemPost(SDL_sem *sem) struct SDL_semaphore { - semaphore_t sem; + semaphore_t sem; }; SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) { - return (SDL_sem *)sem_create(initial_value); + SDL_sem *rv; + + if((rv = (SDL_sem *)malloc(sizeof(SDL_sem)))) + sem_init(&rv->sem, initial_value); + else + SDL_OutOfMemory(); + + return rv; } /* WARNING: @@ -96,80 +103,81 @@ SDL_sem *SDL_CreateSemaphore(Uint32 initial_value) */ void SDL_DestroySemaphore(SDL_sem *sem) { - if ( ! sem ) { - SDL_SetError("Passed a NULL semaphore"); - return; - } + if(!sem) { + SDL_SetError("Passed a NULL semaphore"); + return; + } - sem_destroy(&sem->sem); + sem_destroy(&sem->sem); + free(sem); } int SDL_SemTryWait(SDL_sem *sem) { - int retval; + int retval; - if ( ! sem ) { - SDL_SetError("Passed a NULL semaphore"); - return -1; - } + if(!sem) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } - retval = sem_trywait(&sem->sem); - if (retval==0) return 0; - else return SDL_MUTEX_TIMEDOUT; + retval = sem_trywait(&sem->sem); + if (retval==0) return 0; + else return SDL_MUTEX_TIMEDOUT; - return retval; + return retval; } int SDL_SemWaitTimeout(SDL_sem *sem, Uint32 timeout) { - int retval; + int retval; - if ( ! sem ) { - SDL_SetError("Passed a NULL semaphore"); - return -1; - } + if(!sem) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } - /* A timeout of 0 is an easy case */ - if ( timeout == 0 ) { - return SDL_SemTryWait(sem); - } + /* A timeout of 0 is an easy case */ + if(timeout == 0) { + return SDL_SemTryWait(sem); + } - retval = sem_wait_timed(&sem->sem,timeout); - if (retval==-1) retval= SDL_MUTEX_TIMEDOUT; + retval = sem_wait_timed(&sem->sem,timeout); + if(retval==-1) retval= SDL_MUTEX_TIMEDOUT; - return retval; + return retval; } int SDL_SemWait(SDL_sem *sem) { - if ( ! sem ) { - SDL_SetError("Passed a NULL semaphore"); - return -1; - } + if(!sem) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } - sem_wait(&sem->sem); - return 0; + sem_wait(&sem->sem); + return 0; } Uint32 SDL_SemValue(SDL_sem *sem) { - if ( ! sem ) { - SDL_SetError("Passed a NULL semaphore"); - return -1; - } + if(!sem) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } - return sem_count(&sem->sem); + return sem_count(&sem->sem); } int SDL_SemPost(SDL_sem *sem) { - if ( ! sem ) { - SDL_SetError("Passed a NULL semaphore"); - return -1; - } + if(!sem) { + SDL_SetError("Passed a NULL semaphore"); + return -1; + } - sem_signal(&sem->sem); - return 0; + sem_signal(&sem->sem); + return 0; } #endif /* DISABLE_THREADS */ hooks/post-receive -- The KallistiOS port of SDL. |
From: Lawrence S. <ljs...@us...> - 2014-05-06 16:32:16
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via bdf3aa24bf8141191cb6b666a31313a2fa465242 (commit) from 049709b05651278562daf47629ea4161e56ac230 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit bdf3aa24bf8141191cb6b666a31313a2fa465242 Author: Lawrence Sebald <ljs...@us...> Date: Tue May 6 12:31:47 2014 -0400 Add a convenience function to the MD5 code. ----------------------------------------------------------------------- Summary of changes: addons/include/kos/md5.h | 13 +++++++++++++ addons/libkosutils/md5.c | 9 +++++++++ 2 files changed, 22 insertions(+), 0 deletions(-) diff --git a/addons/include/kos/md5.h b/addons/include/kos/md5.h index 8901cc1..aecd5e4 100644 --- a/addons/include/kos/md5.h +++ b/addons/include/kos/md5.h @@ -70,6 +70,19 @@ void kos_md5_hash_block(kos_md5_cxt_t *cxt, const uint8 *input, uint32 size); */ void kos_md5_finish(kos_md5_cxt_t *cxt, uint8 output[16]); +/** \brief Compute the hash of a block of data with MD5. + + This function is used to hash a full block of data without messing around + with any contexts or anything else of the sort. This is appropriate if you + have all the data you want to hash readily available. It takes care of all + of the context setup and teardown for you. + + \param input The data to hash. + \param size The number of bytes of input data passed in. + \param output Where to store the final message digest. +*/ +void kos_md5(const uint8 *input, uint32 size, uint8 output[16]); + __END_DECLS #endif /* !__KOS_MD5_H */ diff --git a/addons/libkosutils/md5.c b/addons/libkosutils/md5.c index f2528ba..87667f2 100644 --- a/addons/libkosutils/md5.c +++ b/addons/libkosutils/md5.c @@ -272,3 +272,12 @@ void kos_md5_finish(kos_md5_cxt_t *cxt, uint8 output[16]) { output[i] = (uint8)(cxt->hash[i >> 2] >> ((i & 0x03) << 3)); } } + +/* Convenience function for computing an MD5 of a complete block. */ +void kos_md5(const uint8 *input, uint32 size, uint8 output[16]) { + kos_md5_cxt_t cxt; + + kos_md5_start(&cxt); + kos_md5_hash_block(&cxt, input, size); + kos_md5_finish(&cxt, output); +} hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-05-06 00:37:32
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A serial program loader for the Dreamcast.". The branch, master has been updated via 5d88a59d62033a6dcffce8221370675d3601676b (commit) from 21fb648175fa4b4146db2d8568a31e8f7fc0eb16 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 5d88a59d62033a6dcffce8221370675d3601676b Author: Lawrence Sebald <ljs...@us...> Date: Mon May 5 20:36:48 2014 -0400 Add support for speeds > 115200 on OS X and clean up warnings. ----------------------------------------------------------------------- Summary of changes: Makefile.cfg | 8 ++-- host-src/tool/Makefile | 4 +- host-src/tool/dc-tool.c | 99 ++++++++++++++++++++++++++++++----------------- 3 files changed, 69 insertions(+), 42 deletions(-) diff --git a/Makefile.cfg b/Makefile.cfg index ddcffd8..349b217 100644 --- a/Makefile.cfg +++ b/Makefile.cfg @@ -1,7 +1,7 @@ # host compiler and flags HOSTCC = gcc -HOSTCFLAGS = -O2 # -Wall -HOSTLDFLAGS = +HOSTCFLAGS = -O2 -I/usr/local/include # -Wall +HOSTLDFLAGS = -L/usr/local/lib # cygwin probably needs this #HOSTCFLAGS = -O2 -D_WIN32 @@ -13,8 +13,8 @@ TARGETPREFIX = /opt/toolchains/dc/sh-elf # the correct ones for your system # these must point to your sh-elf bfd, not the system one -BFDLIB = -L$(TARGETPREFIX)/lib -lbfd -liberty -BFDINCLUDE = $(TARGETPREFIX)/include +#BFDLIB = -L$(TARGETPREFIX)/lib -lbfd -liberty +#BFDINCLUDE = $(TARGETPREFIX)/include # mac osx # these must point to your sh-elf bfd, not the system one diff --git a/host-src/tool/Makefile b/host-src/tool/Makefile index 072865c..a56c5f0 100644 --- a/host-src/tool/Makefile +++ b/host-src/tool/Makefile @@ -4,10 +4,10 @@ LZOPATH = ../../minilzo.106 CC = $(HOSTCC) CFLAGS = $(HOSTCFLAGS) -DBAUD_RATE=$(SERIALSPEED) -DSERIALDEVICE="\"$(SERIALDEVICE)\"" -DHAVE_GETOPT -DB1500000 -DB500000 -INCLUDE = -I$(LZOPATH) -I$(BFDINCLUDE) +INCLUDE = -I$(LZOPATH) -I/usr/local/include ifdef WITH_BFD - CFLAGS += -DWITH_BFD + CFLAGS += -DWITH_BFD -I$(BFDINCLUDE) LDFLAGS = $(HOSTLDFLAGS) $(BFDLIB) else LDFLAGS = $(HOSTLDFLAGS) -lelf diff --git a/host-src/tool/dc-tool.c b/host-src/tool/dc-tool.c index 4f2eb67..c118abe 100644 --- a/host-src/tool/dc-tool.c +++ b/host-src/tool/dc-tool.c @@ -45,6 +45,10 @@ #include <arpa/inet.h> #include <sys/socket.h> #endif +#ifdef __APPLE__ +#include <IOKit/serial/ioss.h> +#include <sys/ioctl.h> +#endif #include "minilzo.h" #include "syscalls.h" #include "dc-io.h" @@ -527,9 +531,19 @@ int open_serial(char *devicename, unsigned int speed, unsigned int *speedtest) break; } } - - cfsetispeed(&newtio, speedsel); - cfsetospeed(&newtio, speedsel); + +#ifdef __APPLE__ + if(speed > 115200) { + cfsetispeed(&newtio, B115200); + cfsetospeed(&newtio, B115200); + } + else { +#endif + cfsetispeed(&newtio, speedsel); + cfsetospeed(&newtio, speedsel); +#ifdef __APPLE__ + } +#endif // we don't error on these because it *may* still work if (tcflush(dcfd, TCIFLUSH) < 0) { @@ -540,6 +554,16 @@ int open_serial(char *devicename, unsigned int speed, unsigned int *speedtest) printf("warning: your baud rate is likely set incorrectly\n"); } +#ifdef __APPLE__ + if(speed > 115200) { + speed_t s = speed; // Set 14400 baud + if (ioctl(dcfd, IOSSIOSPEED, &speed) < 0) { + perror("IOSSIOSPEED"); + printf("warning: your baud rate is likely set incorrectly\n"); + } + } +#endif + #else BOOL fSuccess; COMMTIMEOUTS ctmoCommPort; @@ -637,30 +661,33 @@ int change_speed(char *device_name, unsigned int speed) send_uint(rv); rv = recv_uint(); printf("done\n"); + return 0; } int open_gdb_socket(int port) { - struct sockaddr_in server_addr; + struct sockaddr_in server_addr; - server_addr.sin_family = AF_INET; - server_addr.sin_port = htons( port ); - server_addr.sin_addr.s_addr = htonl( INADDR_LOOPBACK ); + server_addr.sin_family = AF_INET; + server_addr.sin_port = htons(port); + server_addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - if ( (gdb_server_socket = socket( PF_INET, SOCK_STREAM, IPPROTO_TCP )) < 0 ) { - perror( "error creating gdb server socket" ); - return -1; - } + if((gdb_server_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("error creating gdb server socket"); + return -1; + } - if ( bind( gdb_server_socket, (struct sockaddr*)&server_addr, sizeof( server_addr ) ) < 0 ) { - perror( "error binding gdb server socket" ); - return -1; - } + if(bind(gdb_server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { + perror("error binding gdb server socket"); + return -1; + } - if ( listen( gdb_server_socket, 0 ) < 0 ) { - perror( "error listening to gdb server socket" ); - return -1; - } + if(listen(gdb_server_socket, 0) < 0) { + perror("error listening to gdb server socket"); + return -1; + } + + return 0; } void usage(void) @@ -758,8 +785,8 @@ unsigned int upload(unsigned char *filename, unsigned int address) exit(-1); } - if((inputfd = open(filename, O_RDONLY)) < 0) { - perror(filename); + if((inputfd = open((char *)filename, O_RDONLY)) < 0) { + perror((char *)filename); exit(-1); } @@ -830,10 +857,10 @@ unsigned int upload(unsigned char *filename, unsigned int address) #endif /* if all else fails, send raw bin */ printf("File format is raw binary, start address is 0x%x\n", address); - inputfd = open(filename, O_RDONLY | O_BINARY); + inputfd = open((char *)filename, O_RDONLY | O_BINARY); if(inputfd < 0) { - perror(filename); + perror((char *)filename); exit(-1); } @@ -881,10 +908,10 @@ void download(unsigned char *filename, unsigned int address, struct timeval starttime, endtime; double stime, etime; - outputfd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); + outputfd = open((char *)filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644); if (outputfd < 0) { - perror(filename); + perror((char *)filename); exit(-1); } @@ -944,15 +971,15 @@ void do_console(unsigned char *path, unsigned char *isofile) int isofd; if (isofile) { - isofd = open(isofile, O_RDONLY | O_BINARY); + isofd = open((char *)isofile, O_RDONLY | O_BINARY); if (isofd < 0) - perror(isofile); + perror((char *)isofile); } #ifndef __MINGW32__ if (path) - if (chroot(path)) - perror(path); + if (chroot((char *)path)) + perror((char *)path); #endif while (1) { @@ -1090,7 +1117,7 @@ int main(int argc, char *argv[]) } command = 'x'; filename = malloc(strlen(optarg) + 1); - strcpy(filename, optarg); + strcpy((char *)filename, optarg); break; case 'u': if (command) { @@ -1099,7 +1126,7 @@ int main(int argc, char *argv[]) } command = 'u'; filename = malloc(strlen(optarg) + 1); - strcpy(filename, optarg); + strcpy((char *)filename, optarg); break; case 'd': if (command) { @@ -1108,18 +1135,18 @@ int main(int argc, char *argv[]) } command = 'd'; filename = malloc(strlen(optarg) + 1); - strcpy(filename, optarg); + strcpy((char *)filename, optarg); break; #ifndef __MINGW32__ case 'c': path = malloc(strlen(optarg) + 1); - strcpy(path, optarg); + strcpy((char *)path, optarg); break; #endif case 'i': cdfs_redir = 1; isofile = malloc(strlen(optarg) + 1); - strcpy(isofile, optarg); + strcpy((char *)isofile, optarg); break; case 'a': address = strtoul(optarg, NULL, 0); @@ -1169,8 +1196,8 @@ int main(int argc, char *argv[]) if ((command == 'x') || (command == 'u')) { struct stat statbuf; - if(stat(filename, &statbuf)) { - perror(filename); + if(stat((char *)filename, &statbuf)) { + perror((char *)filename); exit(1); } } hooks/post-receive -- A serial program loader for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-05-03 21:22:32
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 049709b05651278562daf47629ea4161e56ac230 (commit) from 89487109972dec695af7b43c863a4373ab127948 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 049709b05651278562daf47629ea4161e56ac230 Author: Lawrence Sebald <ljs...@us...> Date: Sat May 3 17:21:56 2014 -0400 Add basic g1ata example. ----------------------------------------------------------------------- Summary of changes: examples/dreamcast/g1ata/Makefile | 14 +++ .../{modem/basic => g1ata/atatest}/Makefile | 14 ++-- examples/dreamcast/g1ata/atatest/atatest.c | 96 ++++++++++++++++++++ 3 files changed, 116 insertions(+), 8 deletions(-) create mode 100644 examples/dreamcast/g1ata/Makefile copy examples/dreamcast/{modem/basic => g1ata/atatest}/Makefile (64%) create mode 100644 examples/dreamcast/g1ata/atatest/atatest.c diff --git a/examples/dreamcast/g1ata/Makefile b/examples/dreamcast/g1ata/Makefile new file mode 100644 index 0000000..822eba0 --- /dev/null +++ b/examples/dreamcast/g1ata/Makefile @@ -0,0 +1,14 @@ +# KallistiOS ##version## +# +# examples/dreamcast/g1ata/Makefile +# + +all: + $(KOS_MAKE) -C atatest + +clean: + $(KOS_MAKE) -C atatest clean + +dist: + $(KOS_MAKE) -C atatest dist + diff --git a/examples/dreamcast/modem/basic/Makefile b/examples/dreamcast/g1ata/atatest/Makefile similarity index 64% copy from examples/dreamcast/modem/basic/Makefile copy to examples/dreamcast/g1ata/atatest/Makefile index 8d2e9f2..26e7776 100644 --- a/examples/dreamcast/modem/basic/Makefile +++ b/examples/dreamcast/g1ata/atatest/Makefile @@ -1,11 +1,10 @@ +# KallistiOS ##version## +# +# examples/dreamcast/g1ata/atatest/Makefile # -# Basic modem test program -# Copyright (C)2003 Nick Kochakian -# - -TARGET = example1.elf -OBJS = example1.o +TARGET = atatest.elf +OBJS = atatest.o all: rm-elf $(TARGET) @@ -24,6 +23,5 @@ run: $(TARGET) $(KOS_LOADER) $(TARGET) dist: - rm -f $(OBJS) + rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) - diff --git a/examples/dreamcast/g1ata/atatest/atatest.c b/examples/dreamcast/g1ata/atatest/atatest.c new file mode 100644 index 0000000..07e2042 --- /dev/null +++ b/examples/dreamcast/g1ata/atatest/atatest.c @@ -0,0 +1,96 @@ +/* KallistiOS ##version## + + atatest.c + Copyright (C) 2014 Lawrence Sebald + + This example program simply attempts to read some sectors from the first + partition of an ATA device attached to G1, both over PIO and DMA and then + compares the timing information from both. PIO reads seem to run at about + 3.5 MB/sec, whereas DMA gets around 12.5 MB/sec (quite the improvement). +*/ + +#include <string.h> +#include <stdint.h> +#include <errno.h> + +#include <dc/g1ata.h> + +#include <arch/timer.h> +#include <arch/types.h> + +#include <kos/dbglog.h> +#include <kos/blockdev.h> + +static unsigned char dmabuf[1024 * 512] __attribute__((aligned(32))); +static unsigned char piobuf[1024 * 512] __attribute__((aligned(32))); +static unsigned char tmp[512] __attribute__((aligned(32))); + +int main(int argc, char *argv[]) { + kos_blockdev_t bd_pio, bd_dma; + uint64 spio, epio, sdma, edma, timer; + uint8_t pt; + + dbglog(DBG_DEBUG, "Starting G1 ATA test program...\n"); + g1_ata_init(); + + /* Grab the blockdevs that we'll use to access the partitions. */ + dbglog(DBG_DEBUG, "Looking for first partition...\n"); + if(g1_ata_blockdev_for_partition(0, 0, &bd_pio, &pt)) { + dbglog(DBG_DEBUG, "Couldn't get PIO blockdev for partition!\n"); + return -1; + } + + if(g1_ata_blockdev_for_partition(0, 1, &bd_dma, &pt)) { + dbglog(DBG_DEBUG, "Couldn't get DMA blockdev for partition!\n"); + return -1; + } + + /* For some reason, the first DMA read takes a while... So, read one sector + and discard it so to not mess up the timing stuff below. */ + if(bd_dma.read_blocks(&bd_dma, 1024, 1, tmp)) { + dbglog(DBG_DEBUG, "Couldn't read block 1024 by dma: %s\n", + strerror(errno)); + return -1; + } + + /* Read blocks 0 - 1023 by DMA and print out timing information. */ + dbglog(DBG_DEBUG, "Reading 1024 blocks by DMA!\n"); + + sdma = timer_ms_gettime64(); + if(bd_dma.read_blocks(&bd_dma, 0, 1024, dmabuf)) { + dbglog(DBG_DEBUG, "couldn't read block by DMA: %s\n", strerror(errno)); + return -1; + } + edma = timer_ms_gettime64(); + timer = edma - sdma; + + dbglog(DBG_DEBUG, "DMA read took %llu ms (%f MB/sec)\n", timer, + (512 * 1024) / ((double)timer) / 1000.0); + + /* Read blocks 0 - 1023 by PIO and print out timing information. */ + dbglog(DBG_DEBUG, "Reading 1024 blocks by PIO!\n"); + + spio = timer_ms_gettime64(); + if(bd_pio.read_blocks(&bd_pio, 0, 1024, piobuf)) { + dbglog(DBG_DEBUG, "couldn't read block by PIO: %s\n", strerror(errno)); + return -1; + } + epio = timer_ms_gettime64(); + timer = epio - spio; + + dbglog(DBG_DEBUG, "PIO read took %llu ms (%f MB/sec)\n", timer, + (512 * 1024) / ((double)timer) / 1000.0); + + /* Check the buffers for consistency... */ + if(memcmp(piobuf, dmabuf, 1024 * 512)) { + dbglog(DBG_DEBUG, "Buffers do not match?!\n"); + } + else { + dbglog(DBG_DEBUG, "Both buffers matched!\n"); + } + + /* Clean up... */ + g1_ata_shutdown(); + + return 0; +} hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-05-01 01:47:55
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 89487109972dec695af7b43c863a4373ab127948 (commit) from e69f473ee66b91d8f06589967b5e0ad3c11c520e (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 89487109972dec695af7b43c863a4373ab127948 Author: Lawrence Sebald <ljs...@us...> Date: Wed Apr 30 21:47:29 2014 -0400 Invalidate the operand cache on dma reads in g1ata. ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/hardware/g1ata.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-) diff --git a/kernel/arch/dreamcast/hardware/g1ata.c b/kernel/arch/dreamcast/hardware/g1ata.c index 487a03d..5874bab 100644 --- a/kernel/arch/dreamcast/hardware/g1ata.c +++ b/kernel/arch/dreamcast/hardware/g1ata.c @@ -603,6 +603,9 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, return -1; } + /* Invalidate the dcache over the range of the data. */ + dcache_inval_range((uint32)buf, count * 512); + /* Lock the mutex. It will be unlocked later in the IRQ handler. */ if(g1_ata_mutex_lock()) return -1; hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-05-01 01:33:52
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via e69f473ee66b91d8f06589967b5e0ad3c11c520e (commit) via 728478b3e6874844fd830a26cca469a03a0e4057 (commit) via de6622ee107a577a2d605ec8ef35897b5062e49f (commit) via 45f52f5c60be31be570629e13652a5af7b83c57b (commit) via 934b0206acb04f7568dc0eb17c63c928e90b7a00 (commit) from 0dcf2466b32808a6e5f602654b3c285ed3327336 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit e69f473ee66b91d8f06589967b5e0ad3c11c520e Author: Lawrence Sebald <ljs...@us...> Date: Wed Apr 30 21:33:33 2014 -0400 Update the CHANGELOG for recent commits. commit 728478b3e6874844fd830a26cca469a03a0e4057 Author: Lawrence Sebald <ljs...@us...> Date: Wed Apr 30 21:32:38 2014 -0400 Fixed raw sector reading of non-data CDs. Thanks to SWAT for pointing out that it needed fixing and pushing me until I fixed it. commit de6622ee107a577a2d605ec8ef35897b5062e49f Author: Lawrence Sebald <ljs...@us...> Date: Wed Apr 30 21:12:51 2014 -0400 Use the versions of GMP, MPC, and MPFR that the GCC developers host and apparently recommend (as their download prereqs script will grab them). This actually fixes an issue I ran into when trying to build a Canadian Cross-compiler. Not that anyone probably will need to worry about that... commit 45f52f5c60be31be570629e13652a5af7b83c57b Author: Lawrence Sebald <ljs...@us...> Date: Wed Apr 30 21:11:57 2014 -0400 Don't change the ata device at the end of a g1ata operation, since the cdrom code will change it if needed now. commit 934b0206acb04f7568dc0eb17c63c928e90b7a00 Author: Lawrence Sebald <ljs...@us...> Date: Wed Apr 30 21:10:41 2014 -0400 Add a few notes to the documentation for the pvr function for loading a kimg. ----------------------------------------------------------------------- Summary of changes: doc/CHANGELOG | 5 + kernel/arch/dreamcast/hardware/cdrom.c | 17 +++-- kernel/arch/dreamcast/hardware/g1ata.c | 128 +++++++++++-------------------- kernel/arch/dreamcast/include/dc/pvr.h | 15 ++++- utils/dc-chain/download.sh | 18 ++-- utils/dc-chain/unpack.sh | 6 +- 6 files changed, 88 insertions(+), 101 deletions(-) diff --git a/doc/CHANGELOG b/doc/CHANGELOG index 3be8523..23ab722 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -32,6 +32,11 @@ KallistiOS version 2.0.1 ----------------------------------------------- vblank to actually render to the texture [LS] - *** Modified fs_stat to conform (mostly) to the POSIX standard for the stat function [LS] +- DC Modified the cdrom driver so that it will set itself as the active ATA + device before trying to do any CD related reading [LS] +- DC Fixed potential race conditions between the cdrom code and g1ata [LS] +- DC Fixed full sector reading of non-data CDs (thanks to SWAT for pointing out + that it needed fixing) [LS] KallistiOS version 2.0.0 ----------------------------------------------- - DC Broadband Adapter driver fixes [Dan Potter == DP] diff --git a/kernel/arch/dreamcast/hardware/cdrom.c b/kernel/arch/dreamcast/hardware/cdrom.c index 7efde54..09e613e 100644 --- a/kernel/arch/dreamcast/hardware/cdrom.c +++ b/kernel/arch/dreamcast/hardware/cdrom.c @@ -34,6 +34,11 @@ output and look to make sure. */ +/* Parts of the a CD-ROM sector to read. These are possible values for the + third parameter word sent with the change data type syscall. */ +#define CDROM_READ_WHOLE_SECTOR 0x1000 +#define CDROM_READ_DATA_AREA 0x2000 + /* GD-Rom BIOS calls... named mostly after Marcus' code. None have more than two parameters; R7 (fourth parameter) needs to describe @@ -221,15 +226,15 @@ int cdrom_reinit() { gdc_get_drv_stat(params); if(sector_size != 2352) { cdxa = params[1] == 32; - params[0] = 0; /* 0 = set, 1 = get */ - params[1] = 8192; /* ? */ - params[2] = cdxa ? 2048 : 1024; /* CD-XA mode 1/2 */ - params[3] = sector_size; /* sector size */ + params[0] = 0; /* 0 = set, 1 = get */ + params[1] = CDROM_READ_DATA_AREA; /* Part of the sector to read */ + params[2] = cdxa ? 2048 : 1024; /* Sector type */ + params[3] = sector_size; /* Sector size */ } else { params[0] = 0; - params[1] = 4096; - params[2] = 1024; + params[1] = CDROM_READ_WHOLE_SECTOR; + params[2] = 0; params[3] = 2352; } diff --git a/kernel/arch/dreamcast/hardware/g1ata.c b/kernel/arch/dreamcast/hardware/g1ata.c index 7f2b4f8..487a03d 100644 --- a/kernel/arch/dreamcast/hardware/g1ata.c +++ b/kernel/arch/dreamcast/hardware/g1ata.c @@ -180,20 +180,6 @@ static inline int use_lba28(uint64_t sector, size_t count) { #define CAN_USE_LBA48() ((device.command_sets & (1 << 26))) -static void g1_dma_irq_hnd(uint32 code) { - /* XXXX: Probably should look at the code to make sure it isn't an error. */ - (void)code; - - /* Signal the calling thread to continue, if it is blocking. */ - if(dma_blocking) { - sem_signal(&dma_done); - thd_schedule(1, 0); - dma_blocking = 0; - } - - dma_in_progress = 0; -} - /* Is a G1 DMA in progress? */ int g1_dma_in_progress(void) { return IN32(G1_ATA_DMA_STATUS); @@ -211,6 +197,23 @@ inline int g1_ata_mutex_unlock(void) { return mutex_unlock(&_g1_ata_mutex); } +static void g1_dma_irq_hnd(uint32 code) { + /* XXXX: Probably should look at the code to make sure it isn't an error. */ + (void)code; + + if(dma_in_progress) { + /* Signal the calling thread to continue, if it is blocking. */ + if(dma_blocking) { + sem_signal(&dma_done); + thd_schedule(1, 0); + dma_blocking = 0; + } + + dma_in_progress = 0; + g1_ata_mutex_unlock(); + } +} + /* Set the device select register to select a particular device. */ uint8_t g1_ata_select_device(uint8_t dev) { uint8_t old = IN8(G1_ATA_DEVICE_SELECT); @@ -291,6 +294,9 @@ static int dma_common(uint8_t cmd, size_t nsects, uint32_t addr, int dir, errno = EIO; return -1; } + + /* Since we're blocking, make sure the drive is completely done. */ + g1_ata_wait_bsydrq(); } return 0; @@ -301,7 +307,6 @@ int g1_ata_read_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, int rv = 0; unsigned int i, j; uint8_t nsects = (uint8_t)count; - uint8_t dsel; /* Make sure that we've been initialized and there's a disk attached. */ if(!devices) { @@ -314,17 +319,13 @@ int g1_ata_read_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, return -1; /* Wait for the device to signal it is ready. */ - g1_ata_wait_nbsy(); - - /* For now, just assume we're accessing the slave device. We don't care - about the primary device, since it should always be the GD-ROM drive. */ - dsel = IN8(G1_ATA_DEVICE_SELECT); + g1_ata_wait_bsydrq(); while(count) { nsects = count > 255 ? 255 : (uint8_t)count; count -= nsects; - OUT8(G1_ATA_DEVICE_SELECT, 0xB0 | (h & 0x0F)); + g1_ata_select_device(G1_ATA_SLAVE | (h & 0x0F)); /* Write out the number of sectors we want as well as the cylinder and sector. */ @@ -372,7 +373,6 @@ int g1_ata_read_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, rv = 0; out: - OUT8(G1_ATA_DEVICE_SELECT, dsel); g1_ata_mutex_unlock(); return rv; @@ -383,7 +383,6 @@ int g1_ata_write_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, int rv = 0; unsigned int i, j; uint8_t nsects = (uint8_t)count; - uint8_t dsel; /* Make sure that we've been initialized and there's a disk attached. */ if(!devices) { @@ -396,17 +395,13 @@ int g1_ata_write_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, return -1; /* Wait for the device to signal it is ready. */ - g1_ata_wait_nbsy(); - - /* For now, just assume we're accessing the slave device. We don't care - about the primary device, since it should always be the GD-ROM drive. */ - dsel = IN8(G1_ATA_DEVICE_SELECT); + g1_ata_wait_bsydrq(); while(count) { nsects = count > 255 ? 255 : (uint8_t)count; count -= nsects; - OUT8(G1_ATA_DEVICE_SELECT, 0xB0 | (h & 0x0F)); + g1_ata_select_device(G1_ATA_SLAVE | (h & 0x0F)); /* Write out the number of sectors we want as well as the cylinder and sector. */ @@ -446,11 +441,10 @@ int g1_ata_write_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, } /* Wait for the device to signal that it has finished writing the data. */ - g1_ata_wait_nbsy(); + g1_ata_wait_bsydrq(); rv = 0; - OUT8(G1_ATA_DEVICE_SELECT, dsel); g1_ata_mutex_unlock(); return rv; @@ -460,7 +454,6 @@ int g1_ata_read_lba(uint64_t sector, size_t count, uint16_t *buf) { int rv = 0; unsigned int i, j; uint8_t nsects = (uint8_t)count; - uint8_t dsel; /* Make sure that we've been initialized and there's a disk attached. */ if(!devices) { @@ -485,11 +478,7 @@ int g1_ata_read_lba(uint64_t sector, size_t count, uint16_t *buf) { return -1; /* Wait for the device to signal it is ready. */ - g1_ata_wait_nbsy(); - - /* For now, just assume we're accessing the slave device. We don't care - about the primary device, since it should always be the GD-ROM drive. */ - dsel = IN8(G1_ATA_DEVICE_SELECT); + g1_ata_wait_bsydrq(); while(count) { nsects = count > 255 ? 255 : (uint8_t)count; @@ -497,7 +486,8 @@ int g1_ata_read_lba(uint64_t sector, size_t count, uint16_t *buf) { /* Which mode are we using: LBA28 or LBA48? */ if((sector + nsects) <= 0x0FFFFFFF) { - OUT8(G1_ATA_DEVICE_SELECT, 0xF0 | ((sector >> 24) & 0x0F)); + g1_ata_select_device(G1_ATA_SLAVE | G1_ATA_LBA_MODE | + ((sector >> 24) & 0x0F)); /* Write out the number of sectors we want and the lower 24-bits of the LBA we're looking for. */ @@ -514,7 +504,7 @@ int g1_ata_read_lba(uint64_t sector, size_t count, uint16_t *buf) { OUT8(G1_ATA_COMMAND_REG, ATA_CMD_READ_SECTORS); } else { - OUT8(G1_ATA_DEVICE_SELECT, 0xF0); + g1_ata_select_device(G1_ATA_SLAVE | G1_ATA_LBA_MODE); /* Write out the number of sectors we want and the LBA. */ OUT8(G1_ATA_SECTOR_COUNT, 0); @@ -554,7 +544,6 @@ int g1_ata_read_lba(uint64_t sector, size_t count, uint16_t *buf) { rv = 0; out: - OUT8(G1_ATA_DEVICE_SELECT, dsel); g1_ata_mutex_unlock(); return rv; @@ -563,7 +552,6 @@ out: int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, int block) { int rv = 0; - uint8_t dsel; uint32_t addr; int old, can_lba48 = CAN_USE_LBA48(); @@ -615,7 +603,7 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, return -1; } - /* Lock the mutex. */ + /* Lock the mutex. It will be unlocked later in the IRQ handler. */ if(g1_ata_mutex_lock()) return -1; @@ -637,15 +625,12 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, irq_restore(old); /* Wait for the device to signal it is ready. */ - g1_ata_wait_nbsy(); - - /* For now, just assume we're accessing the slave device. We don't care - about the primary device, since it should always be the GD-ROM drive. */ - dsel = IN8(G1_ATA_DEVICE_SELECT); + g1_ata_wait_bsydrq(); /* Which mode are we using: LBA28 or LBA48? */ if(!can_lba48 || use_lba28(sector, count)) { - OUT8(G1_ATA_DEVICE_SELECT, 0xF0 | ((sector >> 24) & 0x0F)); + g1_ata_select_device(G1_ATA_SLAVE | G1_ATA_LBA_MODE | + ((sector >> 24) & 0x0F)); /* Write out the number of sectors we want and the lower 24-bits of the LBA we're looking for. Note that putting 0 into the sector count @@ -659,7 +644,7 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, rv = dma_common(ATA_CMD_READ_DMA, count, addr, G1_DMA_TO_MEMORY, block); } else { - OUT8(G1_ATA_DEVICE_SELECT, 0xF0); + g1_ata_select_device(G1_ATA_SLAVE | G1_ATA_LBA_MODE); /* Write out the number of sectors we want and the LBA. Note that in LBA48 mode, putting 0 into the sector count register returns 65536 @@ -678,9 +663,6 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, block); } - OUT8(G1_ATA_DEVICE_SELECT, dsel); - g1_ata_mutex_unlock(); - return rv; } @@ -688,7 +670,6 @@ int g1_ata_write_lba(uint64_t sector, size_t count, const uint16_t *buf) { int rv = 0; unsigned int i, j; uint8_t nsects = (uint8_t)count; - uint8_t dsel; /* Make sure that we've been initialized and there's a disk attached. */ if(!devices) { @@ -713,11 +694,7 @@ int g1_ata_write_lba(uint64_t sector, size_t count, const uint16_t *buf) { return -1; /* Wait for the device to signal it is ready. */ - g1_ata_wait_nbsy(); - - /* For now, just assume we're accessing the slave device. We don't care - about the primary device, since it should always be the GD-ROM drive. */ - dsel = IN8(G1_ATA_DEVICE_SELECT); + g1_ata_wait_bsydrq(); while(count) { nsects = count > 255 ? 255 : (uint8_t)count; @@ -725,7 +702,8 @@ int g1_ata_write_lba(uint64_t sector, size_t count, const uint16_t *buf) { /* Which mode are we using: LBA28 or LBA48? */ if((sector + nsects) <= 0x0FFFFFFF) { - OUT8(G1_ATA_DEVICE_SELECT, 0xF0 | ((sector >> 24) & 0x0F)); + g1_ata_select_device(G1_ATA_SLAVE | G1_ATA_LBA_MODE | + ((sector >> 24) & 0x0F)); /* Write out the number of sectors we want and the lower 24-bits of the LBA we're looking for. */ @@ -738,7 +716,7 @@ int g1_ata_write_lba(uint64_t sector, size_t count, const uint16_t *buf) { OUT8(G1_ATA_COMMAND_REG, ATA_CMD_WRITE_SECTORS); } else { - OUT8(G1_ATA_DEVICE_SELECT, 0xF0); + g1_ata_select_device(G1_ATA_SLAVE | G1_ATA_LBA_MODE); /* Write out the number of sectors we want and the LBA. */ OUT8(G1_ATA_SECTOR_COUNT, 0); @@ -767,11 +745,10 @@ int g1_ata_write_lba(uint64_t sector, size_t count, const uint16_t *buf) { } /* Wait for the device to signal that it has finished writing the data. */ - g1_ata_wait_nbsy(); + g1_ata_wait_bsydrq(); rv = 0; - OUT8(G1_ATA_DEVICE_SELECT, dsel); g1_ata_mutex_unlock(); return rv; @@ -780,7 +757,6 @@ int g1_ata_write_lba(uint64_t sector, size_t count, const uint16_t *buf) { int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, int block) { int rv = 0; - uint8_t dsel; uint32_t addr; int old, can_lba48 = CAN_USE_LBA48(); @@ -835,7 +811,7 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, /* Flush the dcache over the range of the data. */ dcache_flush_range((uint32)buf, count * 512); - /* Lock the mutex. */ + /* Lock the mutex. It will be unlocked in the IRQ handler later. */ if(g1_ata_mutex_lock()) return -1; @@ -857,15 +833,12 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, irq_restore(old); /* Wait for the device to signal it is ready. */ - g1_ata_wait_nbsy(); - - /* For now, just assume we're accessing the slave device. We don't care - about the primary device, since it should always be the GD-ROM drive. */ - dsel = IN8(G1_ATA_DEVICE_SELECT); + g1_ata_wait_bsydrq(); /* Which mode are we using: LBA28 or LBA48? */ if(!can_lba48 || use_lba28(sector, count)) { - OUT8(G1_ATA_DEVICE_SELECT, 0xF0 | ((sector >> 24) & 0x0F)); + g1_ata_select_device(G1_ATA_SLAVE | G1_ATA_LBA_MODE | + ((sector >> 24) & 0x0F)); /* Write out the number of sectors we have and the lower 24-bits of the LBA we're looking for. Note that putting 0 into the sector count @@ -880,7 +853,7 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, block); } else { - OUT8(G1_ATA_DEVICE_SELECT, 0xF0); + g1_ata_select_device(G1_ATA_SLAVE | G1_ATA_LBA_MODE); /* Write out the number of sectors we have and the LBA. Note that in LBA48 mode, putting 0 into the sector count register writes 65536 @@ -899,15 +872,10 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, block); } - OUT8(G1_ATA_DEVICE_SELECT, dsel); - g1_ata_mutex_unlock(); - return rv; } int g1_ata_flush(void) { - uint8_t dsel; - /* Make sure that we've been initialized and there's a disk attached. */ if(!devices) { errno = ENXIO; @@ -919,8 +887,7 @@ int g1_ata_flush(void) { return -1; /* Select the slave device. */ - dsel = IN8(G1_ATA_DEVICE_SELECT); - OUT8(G1_ATA_DEVICE_SELECT, 0xF0); + g1_ata_select_device(G1_ATA_SLAVE | G1_ATA_LBA_MODE); timer_spin_sleep(1); /* Flush the disk's write cache to make sure everything gets written out. */ @@ -930,10 +897,7 @@ int g1_ata_flush(void) { OUT8(G1_ATA_COMMAND_REG, ATA_CMD_FLUSH_CACHE); timer_spin_sleep(1); - g1_ata_wait_nbsy(); - - /* Restore the old selected device and return. */ - OUT8(G1_ATA_DEVICE_SELECT, dsel); + g1_ata_wait_bsydrq(); g1_ata_mutex_unlock(); return 0; diff --git a/kernel/arch/dreamcast/include/dc/pvr.h b/kernel/arch/dreamcast/include/dc/pvr.h index 9f8dd1f..f404d7a 100644 --- a/kernel/arch/dreamcast/include/dc/pvr.h +++ b/kernel/arch/dreamcast/include/dc/pvr.h @@ -1839,6 +1839,20 @@ void pvr_txr_load_ex(void * src, pvr_ptr_t dst, uint32 w, uint32 h, uint32 flags \param flags Some set of flags, ORed together. \see pvr_txrload_constants + \note Unless you explicitly tell this function to not + twiddle the texture (by ORing + \ref PVR_TXRLOAD_FMT_NOTWIDDLE or it's equivalent + \ref PVR_TXRLOAD_FMT_TWIDDLED with flags), this + function will twiddle the texture while loading. + Keep that in mind when setting the texture format in + polygon headers later. + \note You cannot specify both + \ref PVR_TXRLOAD_FMT_NOTWIDDLE (or equivalently + \ref PVR_TXRLOAD_FMT_TWIDDLED) and + \ref PVR_TXRLOAD_INVERT_Y in the flags. + \note DMA and Store Queue based loading is not available + from this function if it twiddles the texture while + loading. */ void pvr_txr_load_kimg(kos_img_t *img, pvr_ptr_t dst, uint32 flags); @@ -1960,4 +1974,3 @@ void pvr_dma_shutdown(); __END_DECLS #endif - diff --git a/utils/dc-chain/download.sh b/utils/dc-chain/download.sh index 3c18d76..6f79133 100755 --- a/utils/dc-chain/download.sh +++ b/utils/dc-chain/download.sh @@ -4,9 +4,9 @@ export GCC_VER=4.7.3 export BINUTILS_VER=2.23.2 export NEWLIB_VER=2.0.0 -export GMP_VER=5.1.3 -export MPFR_VER=3.1.2 -export MPC_VER=1.0.1 +export GMP_VER=4.3.2 +export MPFR_VER=2.4.2 +export MPC_VER=0.8.1 while [ "$1" != "" ]; do PARAM=`echo $1 | awk -F= '{print $1}'` @@ -44,17 +44,17 @@ if command -v wget >/dev/null 2>&1; then if [ -n "$GMP_VER" ]; then echo "Downloading GMP $GMP_VER..." - wget -c ftp://ftp.gnu.org/gnu/gmp/gmp-$GMP_VER.tar.bz2 || exit 1 + wget -c ftp://gcc.gnu.org/pub/gcc/infrastructure/gmp-$GMP_VER.tar.bz2 || exit 1 fi if [ -n "$MPFR_VER" ]; then echo "Downloading MPFR $MPFR_VER..." - wget -c http://www.mpfr.org/mpfr-current/mpfr-$MPFR_VER.tar.bz2 || exit 1 + wget -c ftp://gcc.gnu.org/pub/gcc/infrastructure/mpfr-$MPFR_VER.tar.bz2 || exit 1 fi if [ -n "$MPC_VER" ]; then echo "Downloading MPC $MPC_VER..." - wget -c http://www.multiprecision.org/mpc/download/mpc-$MPC_VER.tar.gz || exit 1 + wget -c ftp://gcc.gnu.org/pub/gcc/infrastructure/mpc-$MPC_VER.tar.gz || exit 1 fi elif command -v curl >/dev/null 2>&1; then echo "Downloading Binutils $BINUTILS_VER..." @@ -66,17 +66,17 @@ elif command -v curl >/dev/null 2>&1; then if [ -n "$GMP_VER" ]; then echo "Downloading GMP $GMP_VER..." - curl -C -O ftp://ftp.gnu.org/gnu/gmp/gmp-$GMP_VER.tar.bz2 || exit 1 + curl -C - -O ftp://gcc.gnu.org/pub/gcc/infrastructure/gmp-$GMP_VER.tar.bz2 || exit 1 fi ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-04-29 00:41:31
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 0dcf2466b32808a6e5f602654b3c285ed3327336 (commit) from fdcc2e00c9862e2def5b3768c6a7957321073f5c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 0dcf2466b32808a6e5f602654b3c285ed3327336 Author: Lawrence Sebald <ljs...@us...> Date: Mon Apr 28 20:41:17 2014 -0400 Remove stat_t from fs.h. ----------------------------------------------------------------------- Summary of changes: include/kos/fs.h | 17 ----------------- 1 files changed, 0 insertions(+), 17 deletions(-) diff --git a/include/kos/fs.h b/include/kos/fs.h index adadd67..d48f5f4 100644 --- a/include/kos/fs.h +++ b/include/kos/fs.h @@ -51,23 +51,6 @@ typedef struct kos_dirent { /* Forward declaration */ struct vfs_handler; -/** \brief File status information. - - This structure, while different from the standard POSIX stat structure, - provides much of the same information. We limit it to only what is relevant - for KOS. - - \headerfile kos/fs.h. -*/ -typedef struct { - struct vfs_handler *dev; /**< \brief The VFS handler for this file/dir */ - uint32 unique; /**< \brief A unique identifier on the VFS for this file/dir */ - uint32 type; /**< \brief File/Dir type */ - uint32 attr; /**< \brief Attributes */ - off_t size; /**< \brief Total file size, if applicable */ - time_t time; /**< \brief Last access/mod/change time (depends on VFS) */ -} stat_t; - /* stat_t.unique */ /**< \brief stat_t.unique: Constant to use denoting the file has no unique ID */ #define STAT_UNIQUE_NONE 0 hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-04-29 00:40:30
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via fdcc2e00c9862e2def5b3768c6a7957321073f5c (commit) from c8dcfa1aa32d65a48334cb439fc5794d9d27c330 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fdcc2e00c9862e2def5b3768c6a7957321073f5c Author: Lawrence Sebald <ljs...@us...> Date: Mon Apr 28 20:38:42 2014 -0400 Make the cdrom code aware of the g1ata stuff. This involved making sure that g1_ata_* locks the same mutex as the cdrom stuff and making sure the cdrom stuff sets up the device select register properly before trying to access the cdrom (since the BIOS syscalls don't do it). There's still a bit of cleanup related to all of this to do in g1_ata_*, but it works at this point, so I'm committing it now. ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/hardware/cdrom.c | 59 +++++---- kernel/arch/dreamcast/hardware/g1ata.c | 205 +++++++++++++++++++++++------- kernel/arch/dreamcast/include/dc/g1ata.h | 98 ++++++++++++++ 3 files changed, 295 insertions(+), 67 deletions(-) diff --git a/kernel/arch/dreamcast/hardware/cdrom.c b/kernel/arch/dreamcast/hardware/cdrom.c index 9d082fb..7efde54 100644 --- a/kernel/arch/dreamcast/hardware/cdrom.c +++ b/kernel/arch/dreamcast/hardware/cdrom.c @@ -2,11 +2,14 @@ cdrom.c - (c)2000 Dan Potter + Copyright (C) 2000 Dan Potter + Copyright (C) 2014 Lawrence Sebald */ #include <dc/cdrom.h> +#include <dc/g1ata.h> + #include <kos/thread.h> #include <kos/mutex.h> @@ -86,7 +89,7 @@ static void gdc_abort_cmd(int cmd) { #endif /* The CD access mutex */ -static mutex_t mutex; +mutex_t _g1_ata_mutex; static int initted = 0; static int sector_size = 2048; /*default 2048, 2352 for raw data reading*/ @@ -100,6 +103,9 @@ int cdrom_exec_cmd(int cmd, void *param) { int status[4] = {0}; int f, n; + /* Make sure to select the GD-ROM drive. */ + g1_ata_select_device(G1_ATA_MASTER); + /* Submit the command and wait for it to finish */ f = gdc_req_cmd(cmd, param); @@ -139,13 +145,16 @@ int cdrom_get_status(int *status, int *disc_type) { flushing, so make sure we're not interrupting something already in progress. */ if(irq_inside_int()) { - if(mutex_is_locked(&mutex)) + if(mutex_trylock(&_g1_ata_mutex)) return -1; } else { - mutex_lock(&mutex); + mutex_lock(&_g1_ata_mutex); } + /* Make sure to select the GD-ROM drive. */ + g1_ata_select_device(G1_ATA_MASTER); + rv = gdc_get_drv_stat(params); if(rv >= 0) { @@ -163,8 +172,7 @@ int cdrom_get_status(int *status, int *disc_type) { *disc_type = -1; } - if(!irq_inside_int()) - mutex_unlock(&mutex); + mutex_unlock(&_g1_ata_mutex); return rv; } @@ -176,12 +184,15 @@ int cdrom_reinit() { uint32 params[4]; int timeout; - mutex_lock(&mutex); + mutex_lock(&_g1_ata_mutex); /* Try a few times; it might be busy. If it's still busy after this loop then it's probably really dead. */ timeout = 10 * 1000 / 20; /* 10 second timeout */ + /* Make sure to select the GD-ROM drive. */ + g1_ata_select_device(G1_ATA_MASTER); + while(timeout > 0) { r = cdrom_exec_cmd(CMD_INIT, NULL); @@ -228,7 +239,7 @@ int cdrom_reinit() { } exit: - mutex_unlock(&mutex); + mutex_unlock(&_g1_ata_mutex); return rv; } @@ -240,13 +251,13 @@ int cdrom_read_toc(CDROM_TOC *toc_buffer, int session) { } params; int rv; - mutex_lock(&mutex); + mutex_lock(&_g1_ata_mutex); params.session = session; params.buffer = toc_buffer; rv = cdrom_exec_cmd(CMD_GETTOC2, ¶ms); - mutex_unlock(&mutex); + mutex_unlock(&_g1_ata_mutex); return rv; } @@ -259,7 +270,7 @@ int cdrom_read_sectors(void *buffer, int sector, int cnt) { } params; int rv; - mutex_lock(&mutex); + mutex_lock(&_g1_ata_mutex); params.sec = sector; /* Starting sector */ params.num = cnt; /* Number of sectors */ @@ -267,7 +278,7 @@ int cdrom_read_sectors(void *buffer, int sector, int cnt) { params.dunno = 0; /* ? */ rv = cdrom_exec_cmd(CMD_PIOREAD, ¶ms); - mutex_unlock(&mutex); + mutex_unlock(&_g1_ata_mutex); return rv; } @@ -312,14 +323,14 @@ int cdrom_cdda_play(uint32 start, uint32 end, uint32 repeat, int mode) { params.end = end; params.repeat = repeat; - mutex_lock(&mutex); + mutex_lock(&_g1_ata_mutex); if(mode == CDDA_TRACKS) rv = cdrom_exec_cmd(CMD_PLAY, ¶ms); else rv = cdrom_exec_cmd(CMD_PLAY2, ¶ms); - mutex_unlock(&mutex); + mutex_unlock(&_g1_ata_mutex); return rv; } @@ -328,9 +339,9 @@ int cdrom_cdda_play(uint32 start, uint32 end, uint32 repeat, int mode) { int cdrom_cdda_pause() { int rv; - mutex_lock(&mutex); + mutex_lock(&_g1_ata_mutex); rv = cdrom_exec_cmd(CMD_PAUSE, NULL); - mutex_unlock(&mutex); + mutex_unlock(&_g1_ata_mutex); return rv; } @@ -339,9 +350,9 @@ int cdrom_cdda_pause() { int cdrom_cdda_resume() { int rv; - mutex_lock(&mutex); + mutex_lock(&_g1_ata_mutex); rv = cdrom_exec_cmd(CMD_RELEASE, NULL); - mutex_unlock(&mutex); + mutex_unlock(&_g1_ata_mutex); return rv; } @@ -350,9 +361,9 @@ int cdrom_cdda_resume() { int cdrom_spin_down() { int rv; - mutex_lock(&mutex); + mutex_lock(&_g1_ata_mutex); rv = cdrom_exec_cmd(CMD_STOP, NULL); - mutex_unlock(&mutex); + mutex_unlock(&_g1_ata_mutex); return rv; } @@ -374,11 +385,14 @@ int cdrom_init() { (void)bios[p]; } + /* Make sure to select the GD-ROM drive. */ + g1_ata_select_device(G1_ATA_MASTER); + /* Reset system functions */ gdc_init_system(); /* Initialize mutex */ - mutex_init(&mutex, MUTEX_TYPE_NORMAL); + mutex_init(&_g1_ata_mutex, MUTEX_TYPE_NORMAL); /* Do an initial initialization */ cdrom_reinit(); @@ -390,7 +404,6 @@ void cdrom_shutdown() { if(!initted) return; - mutex_destroy(&mutex); + mutex_destroy(&_g1_ata_mutex); initted = 0; } - diff --git a/kernel/arch/dreamcast/hardware/g1ata.c b/kernel/arch/dreamcast/hardware/g1ata.c index a8862e7..7f2b4f8 100644 --- a/kernel/arch/dreamcast/hardware/g1ata.c +++ b/kernel/arch/dreamcast/hardware/g1ata.c @@ -13,6 +13,7 @@ #include <kos/dbglog.h> #include <kos/sem.h> +#include <kos/mutex.h> #include <arch/timer.h> #include <arch/cache.h> @@ -48,7 +49,7 @@ fun stuff in here comes from. Register locations and such were derived from a couple of different sources, including Quzar's GDINFO program, my own SPI CD Player program (which I should eventually release), and the source code to - the emulator NullDC. Also, various postings at OSDev were quite useful in + the emulator NullDC. Also, various postings at OSDev were quite useful in working some of this out. Anyway, that's enough for this wall of text... @@ -152,14 +153,23 @@ typedef struct ata_devdata { static int initted = 0; static int devices = 0; +static uint8_t dev_selected = 0x00; +static uint8_t orig_dev = 0x00; /* Variables related to DMA. */ static int dma_in_progress = 0; static int dma_blocking = 0; static semaphore_t dma_done = SEM_INITIALIZER(0); -#define g1_ata_wait_nbsy() \ - do {} while((IN8(G1_ATA_ALTSTATUS) & G1_ATA_SR_BSY)) +/* From cdrom.c */ +extern mutex_t _g1_ata_mutex; + +#define g1_ata_wait_status(n) \ + do {} while((IN8(G1_ATA_ALTSTATUS) & (n))) + +#define g1_ata_wait_nbsy() g1_ata_wait_status(G1_ATA_SR_BSY) + +#define g1_ata_wait_bsydrq() g1_ata_wait_status(G1_ATA_SR_DRQ | G1_ATA_SR_BSY) #define g1_ata_wait_drdy() \ do {} while(!(IN8(G1_ATA_ALTSTATUS) & G1_ATA_SR_DRDY)) @@ -189,6 +199,54 @@ int g1_dma_in_progress(void) { return IN32(G1_ATA_DMA_STATUS); } +/* G1 mutex handling. */ +inline int g1_ata_mutex_lock(void) { + if(irq_inside_int()) + return mutex_trylock(&_g1_ata_mutex); + else + return mutex_lock(&_g1_ata_mutex); +} + +inline int g1_ata_mutex_unlock(void) { + return mutex_unlock(&_g1_ata_mutex); +} + +/* Set the device select register to select a particular device. */ +uint8_t g1_ata_select_device(uint8_t dev) { + uint8_t old = IN8(G1_ATA_DEVICE_SELECT); + + /* Are we actually switching devices? */ + if(((dev ^ dev_selected) & 0x10)) { + /* We might run into some trouble here if this is called in an IRQ + handler, so treat that case specially... */ + if(irq_inside_int()) { + /* If there's a DMA going, then punt. We don't want to sit around + forever waiting... */ + if(g1_dma_in_progress()) + return 0x0F; + + if(IN8(G1_ATA_ALTSTATUS) & (G1_ATA_SR_DRQ | G1_ATA_SR_BSY)) + return 0x0F; + } + else { + /* Wait for any in-progress DMA transfers to finish. */ + while(g1_dma_in_progress()) + thd_pass(); + + /* According to section 7.10 of the ATA-5 spec, setting the device + select register with either of BSY or DRQ asserted produces an + indeterminite result. */ + g1_ata_wait_bsydrq(); + } + } + + /* Write the register value out and return the old value. */ + OUT8(G1_ATA_DEVICE_SELECT, dev); + dev_selected = dev; + + return old; +} + /* This one is an inline function since it needs to return something... */ static inline int g1_ata_wait_drq(void) { uint8_t val = IN8(G1_ATA_ALTSTATUS); @@ -251,6 +309,10 @@ int g1_ata_read_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, return -1; } + /* Lock the mutex. */ + if(g1_ata_mutex_lock()) + return -1; + /* Wait for the device to signal it is ready. */ g1_ata_wait_nbsy(); @@ -268,7 +330,7 @@ int g1_ata_read_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, sector. */ OUT8(G1_ATA_SECTOR_COUNT, nsects); OUT8(G1_ATA_CHS_SECTOR, s); - OUT8(G1_ATA_CHS_CYL_LOW, (uint8_t)((c >> 0) & 0xFF)); + OUT8(G1_ATA_CHS_CYL_LOW, (uint8_t)((c >> 0) & 0xFF)); OUT8(G1_ATA_CHS_CYL_HIGH, (uint8_t)((c >> 8) & 0xFF)); /* Wait until the drive is ready to accept the command. */ @@ -311,6 +373,8 @@ int g1_ata_read_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, out: OUT8(G1_ATA_DEVICE_SELECT, dsel); + g1_ata_mutex_unlock(); + return rv; } @@ -327,6 +391,10 @@ int g1_ata_write_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, return -1; } + /* Lock the mutex. */ + if(g1_ata_mutex_lock()) + return -1; + /* Wait for the device to signal it is ready. */ g1_ata_wait_nbsy(); @@ -344,7 +412,7 @@ int g1_ata_write_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, sector. */ OUT8(G1_ATA_SECTOR_COUNT, nsects); OUT8(G1_ATA_CHS_SECTOR, s); - OUT8(G1_ATA_CHS_CYL_LOW, (uint8_t)((c >> 0) & 0xFF)); + OUT8(G1_ATA_CHS_CYL_LOW, (uint8_t)((c >> 0) & 0xFF)); OUT8(G1_ATA_CHS_CYL_HIGH, (uint8_t)((c >> 8) & 0xFF)); /* Wait until the drive is ready to accept the command. */ @@ -377,9 +445,14 @@ int g1_ata_write_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, } } + /* Wait for the device to signal that it has finished writing the data. */ + g1_ata_wait_nbsy(); + rv = 0; OUT8(G1_ATA_DEVICE_SELECT, dsel); + g1_ata_mutex_unlock(); + return rv; } @@ -407,6 +480,10 @@ int g1_ata_read_lba(uint64_t sector, size_t count, uint16_t *buf) { return -1; } + /* Lock the mutex. */ + if(g1_ata_mutex_lock()) + return -1; + /* Wait for the device to signal it is ready. */ g1_ata_wait_nbsy(); @@ -425,8 +502,8 @@ int g1_ata_read_lba(uint64_t sector, size_t count, uint16_t *buf) { /* Write out the number of sectors we want and the lower 24-bits of the LBA we're looking for. */ OUT8(G1_ATA_SECTOR_COUNT, nsects); - OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); - OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); + OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); + OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 16) & 0xFF)); /* Wait until the drive is ready to accept the command. */ @@ -441,12 +518,12 @@ int g1_ata_read_lba(uint64_t sector, size_t count, uint16_t *buf) { /* Write out the number of sectors we want and the LBA. */ OUT8(G1_ATA_SECTOR_COUNT, 0); - OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 24) & 0xFF)); - OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 32) & 0xFF)); + OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 24) & 0xFF)); + OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 32) & 0xFF)); OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 40) & 0xFF)); OUT8(G1_ATA_SECTOR_COUNT, nsects); - OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); - OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); + OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); + OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 16) & 0xFF)); /* Wait until the drive is ready to accept the command. */ @@ -475,9 +552,11 @@ int g1_ata_read_lba(uint64_t sector, size_t count, uint16_t *buf) { } rv = 0; - + out: OUT8(G1_ATA_DEVICE_SELECT, dsel); + g1_ata_mutex_unlock(); + return rv; } @@ -536,12 +615,17 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, return -1; } + /* Lock the mutex. */ + if(g1_ata_mutex_lock()) + return -1; + /* Disable IRQs temporarily... */ old = irq_disable(); /* Make sure there is no DMA in progress already. */ if(dma_in_progress || g1_dma_in_progress()) { irq_restore(old); + g1_ata_mutex_unlock(); dbglog(DBG_KDEBUG, "g1_ata_read_lba_dma: DMA in progress\n"); errno = EIO; return -1; @@ -567,8 +651,8 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, the LBA we're looking for. Note that putting 0 into the sector count register returns 256 sectors. */ OUT8(G1_ATA_SECTOR_COUNT, (uint8_t)count); - OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); - OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); + OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); + OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 16) & 0xFF)); /* Do the rest of the work... */ @@ -581,12 +665,12 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, LBA48 mode, putting 0 into the sector count register returns 65536 sectors (not that we have that much RAM on the Dreamcast). */ OUT8(G1_ATA_SECTOR_COUNT, (uint8_t)(count >> 8)); - OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 24) & 0xFF)); - OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 32) & 0xFF)); + OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 24) & 0xFF)); + OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 32) & 0xFF)); OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 40) & 0xFF)); OUT8(G1_ATA_SECTOR_COUNT, (uint8_t)count); - OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); - OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); + OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); + OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 16) & 0xFF)); /* Do the rest of the work... */ @@ -595,6 +679,8 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, } OUT8(G1_ATA_DEVICE_SELECT, dsel); + g1_ata_mutex_unlock(); + return rv; } @@ -622,6 +708,10 @@ int g1_ata_write_lba(uint64_t sector, size_t count, const uint16_t *buf) { return -1; } + /* Lock the mutex. */ + if(g1_ata_mutex_lock()) + return -1; + /* Wait for the device to signal it is ready. */ g1_ata_wait_nbsy(); @@ -640,8 +730,8 @@ int g1_ata_write_lba(uint64_t sector, size_t count, const uint16_t *buf) { /* Write out the number of sectors we want and the lower 24-bits of the LBA we're looking for. */ OUT8(G1_ATA_SECTOR_COUNT, nsects); - OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); - OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); + OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); + OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 16) & 0xFF)); /* Write out the command to the device. */ @@ -652,12 +742,12 @@ int g1_ata_write_lba(uint64_t sector, size_t count, const uint16_t *buf) { /* Write out the number of sectors we want and the LBA. */ OUT8(G1_ATA_SECTOR_COUNT, 0); - OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 24) & 0xFF)); - OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 32) & 0xFF)); ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-04-28 15:51:14
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via c8dcfa1aa32d65a48334cb439fc5794d9d27c330 (commit) via 31dc4c1ba48ad25d97836303502c50d492bf962f (commit) via 96ac1dcaeda41acdf8e9e996feb1da34fe58c4e4 (commit) via 8f72cd745b5f4b201935d3de0f365d64f8d81550 (commit) via 45145432bf94d5138666fa95faf6750f2769f76e (commit) from 924da83bb1acdf14e45570181d011cd3481f6e80 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit c8dcfa1aa32d65a48334cb439fc5794d9d27c330 Author: Lawrence Sebald <ljs...@us...> Date: Mon Apr 28 11:50:46 2014 -0400 Update the release notes a bit for the current state of things. commit 31dc4c1ba48ad25d97836303502c50d492bf962f Author: Lawrence Sebald <ljs...@us...> Date: Mon Apr 28 09:43:06 2014 -0400 Fix a bit of nonsensical commenting. commit 96ac1dcaeda41acdf8e9e996feb1da34fe58c4e4 Author: Lawrence Sebald <ljs...@us...> Date: Sun Apr 27 19:31:58 2014 -0400 Update the FAQ to remove some irrelevant stuff and add a note about the modem to the network portion of the document. commit 8f72cd745b5f4b201935d3de0f365d64f8d81550 Author: Lawrence Sebald <ljs...@us...> Date: Sun Apr 27 19:27:12 2014 -0400 Update the README to remove some stuff about old ports and update the formatting section. commit 45145432bf94d5138666fa95faf6750f2769f76e Author: Lawrence Sebald <ljs...@us...> Date: Mon Apr 21 10:46:27 2014 -0400 Adding generated/downloaded stuff from dc-chain to the .gitignore. ----------------------------------------------------------------------- Summary of changes: .gitignore | 4 +- doc/FAQ | 37 ++++++----- doc/README | 100 ++++++++--------------------- doc/RELNOTES | 66 ++++++++++++++++++-- kernel/arch/dreamcast/include/dc/cdrom.h | 2 +- 5 files changed, 112 insertions(+), 97 deletions(-) diff --git a/.gitignore b/.gitignore index 5bf31ef..979f5c3 100644 --- a/.gitignore +++ b/.gitignore @@ -30,4 +30,6 @@ examples/dreamcast/conio/adventure/setup examples/dreamcast/png/romdisk_boot.img examples/dreamcast/pvr/modifier_volume_tex/romdisk/fruit.kmg examples/dreamcast/pvr/texture_render/texture_render.bin - +utils/dc-chain/logs +utils/dc-chain/*.tar.bz2 +utils/dc-chain/*.tar.gz diff --git a/doc/FAQ b/doc/FAQ index 67d281e..4d6402d 100644 --- a/doc/FAQ +++ b/doc/FAQ @@ -1,6 +1,6 @@ KallistiOS ##version## FAQ Copyright (C) 2001 Dan Potter -Copyright (C) 2012, 2013 Lawrence Sebald +Copyright (C) 2012-2014 Lawrence Sebald Here you may find some answers to some common questions we hear regarding the usage of KOS. We will be adding more to this file over @@ -289,7 +289,7 @@ make sure there's a /tmp path mount for bin2o's usage. 2.1 Q) How can I determine how much RAM I have allocated / how much RAM my -program is using? +program is using? A) This won't always be accurate, but in the kernel space you can call malloc_stats(). The output is sent to the kernel console. @@ -321,13 +321,17 @@ similar facility for the PVR on the DC port. Q) Does KOS have any kind of TCP/IP stack? Network support at all? -A) Yes. There is a very primitive and rudimentary driver for the Sega -broadband adapter (an RTL8193C based 10/100 card) and the Lan Adapter on -the DC. With regards to TCP/IP and friends, there are two choices: either -you can use the built-in network stack or you can use lwIP, which is in -the kos-ports tree. Note that lwIP is pretty much considered deprecated -now, and isn't actively tested anymore. You should use the internal -network stack for all new code. +A) Yes. There is a working driver for the Sega broadband adapter (an +RTL8193C based 10/100 card) and the Lan Adapter on the DC. With regards +to TCP/IP and friends, there are two choices: either you can use the +built-in network stack or you can use lwIP, which is in the kos-ports +tree. Note that lwIP is pretty much considered deprecated now, and +isn't actively tested anymore. You should use the internal network stack +for all new code. + +There is also a driver for the Dreamcast modem, however there is no PPP +stack, which would be needed to connect to the internet and the rest of +the TCP/IP stack with it. 3.2 @@ -346,7 +350,7 @@ thread primitives now in KOS this might not be as hard. 4 --- Building ----------------------------------------------------- -4.1 +4.1 Q) I'm having an issue building KOS; it gives me errors about not finding Makefiles or not finding include files. @@ -363,7 +367,7 @@ Q) Where is the source to bin2o? All your other stuff has source... A) Examine the file more closely. It _is_ the source code =). bin2o is a bash shell script that runs from a real bash on a *nix, or under the -Cygwin bash. There were some issues with it running under Cygwin +Cygwin bash. There were some issues with it running under Cygwin previously but those should now be fixed. @@ -374,13 +378,10 @@ previously but those should now be fixed. Q) I work on a DC; I don't have a serial cable so how can I see the debug output? -Q) I work on a PS2; how can I see debug output? - -A) For #1, use dc-load-ip and it has a very nice console mode also. For -#2, I give you basically the same answer: put ps2-load-ip on your Linux -memory card and add it to your RTE menu. Use that to load any KOS -programs and you will have a choice of both GS-based and ethernet-based -consoles. +A) Use dc-load-ip with your broadband adapter or lan adapter on the +Dreamcast. If you don't have one of those, you might look into fb_console, +which you can redirect to either the whole framebuffer or a texture +somewhere in VRAM. 5.2 diff --git a/doc/README b/doc/README index 78ec43c..b8c79f8 100644 --- a/doc/README +++ b/doc/README @@ -1,15 +1,15 @@ KallistiOS ##version## README Copyright (C) 2000-2003 Dan Potter -Copyright (C) 2012-2013 Lawrence Sebald +Copyright (C) 2012-2014 Lawrence Sebald OVERVIEW -------- KallistiOS is a pseudo-real-time operating system for gaming consoles, licensed under the terms of the *new* BSD license (the one without the -advertising clause). It has currently been ported to the Dreamcast*, -Gameboy Advance*, PlayStation 2*, and Intel* ia32 platforms, though the -DC port is still the most advanced and functional of the lot. +advertising clause). It is currently available for the Dreamcast*, but +ports previously existed for the Gameboy Advance*, PlayStation 2*, and +Intel* ia32 platforms, although none were particularly complete. Depending on whether you wish to see the fnords, you can pronounce it "kallisti-o's" (like a cereal) or "kallisti o s" (like an operating @@ -92,11 +92,8 @@ PREREQUISITES ------------- Building KallistiOS from source entirely requires two things: - GNU Binutils / GCC, cross-compile to the platform of your choice; for - DC this is a compiler targeted for "sh-elf", for GBA this is - a compiler targeted for "arm-elf", and for PS2 you'll need the - PS2DEV "ee" compiler. On ia32, you can just use any PC version - of GCC that writes ELF files (e.g., Linux compiler). See below about - version notes. + DC this is a compiler targeted for "sh-elf", as well as (optionally) + a compiler targeted for "arm-eabi". See below about version notes. - GNU Binutils / GCC / GNU Make for your host platform For the Dreamcast version, a Makefile is provided to build the requisite @@ -105,10 +102,8 @@ GCC, Binutils, and Newlib versions in the utils/dc-chain directory. If you don't have any of the above, please see one of the following sites for some more instructions (and perhaps a build script that may help you): -DC: http://gamedev.allusion.net/softprj/kos/setup.php -DC: http://dcemulation.org/ -GBA: http://www.gbadev.org/ -PS2: http://wiki.ps2dev.org/ + http://gamedev.allusion.net/softprj/kos/setup.php + http://dcemulation.org/ On the Dreamcast, the 4.x series of GCC works pretty well. Look at the patches provided in utils/dc-chain/patches to see what versions have been tested and @@ -129,20 +124,6 @@ You do not necessarily need an ARM version of GCC to build KOS for the DC, as precompiled binaries are provided of the necessary code. As long as you don't intend to modify the sound driver, you don't need the ARM tools. -On the GBA, any fairly new GCC 3.0.x and above works fine. It includes the -new ARM-supplied backend for that CPU target. It also provides a compiler -that works with both ARM and Thumb mode code, including interworking -(though good luck getting that to work!). - -For PS2, you're stuck with a 2.95.2 derivative for the EE, because that's -what Sony provided and no one has managed to fully update to the latest -versions AFAIK. YMMV, there may be a new one by now. Note that the PS2 port -currently only builds for the RTE sub-arch, which is the loader DVD used -with the PS2 Linux Kit. So using KOS for PS2 currently requires that you -have a Linux Kit. You used to be able to buy one here: - -http://us.playstation.com/hardware/more/SCPH-97047.asp - BUILDING -------- @@ -207,10 +188,20 @@ contains a lot of reformatting, sloppy coding, things at cross-purposes with the primary thrust of KOS, etc), but I will make an effort to at least examine and comment on any submitted patches. -Please also read coding_style.txt if you want to submit things to the -KOS core. Except in some exceptional circumstances, I will want the -code to match up style-wise in at least the core lib. Things in add-ons -aren't quite as important. +Code should be relatively well formatted, especially in the core library/kernel +portions. There are tools out there to help you reformat your code so that it +will match the rest of KOS a lot more nicely. One such tool is Artistic Style +(http://astyle.sourceforge.net/). Here's a nice set of flags to feed to the +astyle program to make your code match up nicely with the rest of KOS: + astyle --style=attach -s4 -c -S -w -y -f -U -p -m0 -xn -xc -xl -xk -C -N -Y \ + -k3 -xL -xM -xQ -xP0 [your files go here] +I don't guarantee that this produces the exact same formatting as the rest of +the code, but it should be pretty much correct (and I won't reject your patch +for styling if you use this set of flags to astyle on it). You might also want +to take a look at the coding_style.txt file (in the same directory as this +README in the KOS tree) for some rationale for most of that formatting stuff. +Note that some of that has changed over time (mainly when the maintainer of KOS +changes), but it is still mostly right. ;-) OS MODE IS GONE FOR GOOD @@ -234,45 +225,10 @@ Dreamcast* and look at sndmp3_mpglib.c in that dir. - libs3m is present but doesn't really work. It needs serious porting work. -Gameboy Advance* - -- This port is was being maintained by Gil Megidish, however it appears - that is no longer the case. If someone wants to maintain it, please let - me know! Otherwise, this port will probably be removed from the tree in - the not-too-distant future. -- There is not a lot of hardware support yet. IRQs aren't even supported, - so don't even think about trying to use threads yet =). This port is - somewhat immature however, so I expect the support to improve over - time. -- KOS is currently configured to run as Thumb code from the ROM. This can - be changed by editing the config script to set the compiler flags and - editing kernel/arch/gba/kernel/startup.s to remove the "bx" call and - make it a regular jump. -- In future versions I hope to have a more elegant system to combine Thumb - and ARM mode code (including automated copying of your ARM code into RAM - with the data segment). You can see the beginnings of this in the linker - script. - -PlayStation 2* - -- This port currently only supports booting on the Linux Kit RTE. If anyone - who has a raw PS2DEV setup would like to port things around to work on - the raw PS2 as well, I'd be happy to accept any help. -- It is designed to be used with ps2-load-ip as a loader. -- There is basically no hardware support yet, just a CPU/kernel-core port. -- This port is pretty much unmaintained at this point. Unless someone steps - up to maintain it, it will probably be cut from the tree sometime in the - future. - -Intel* IA32 - -- This platform was essentially a test just to see if it could be done, - but I suspect it would be pretty useful for people writing things like - embedded MP3 players. -- It was written using the very old KOS 1.3.x snapshot, so it probably - doesn't compile right now. But it could probably be fixed pretty easily. -- If nobody is interested in this port, it will likely be removed from the - tree in the nearish future as well. +There are no other supported platforms after KOS 2.0.0. They were all pretty +much broken and unmaintained anyway, so they were removed shortly after the +release of KOS 2.0.0. + END --- @@ -288,9 +244,9 @@ to SourceForge for all console-related things. http://gamedev.allusion.net/ -* "Sega" and "Dreamcast" are registered trademarks of Sega Enterprises, Ltd. +* "Sega" and "Dreamcast" are registered trademarks of Sega Enterprises, Ltd. "Nintendo" and "Gameboy Advance" are registered trademarks of Nintendo of America - Kalisto Software is a registered trademark of Kalisto Software, Inc. + Kalisto Software is a registered trademark of Kalisto Software, Inc. "PlayStation" is a registered trademark of Sony Computer Entertainment America "Intel" is a registered trademark of Intel, Inc. Any other trademarks are trademarks of their respective owners. diff --git a/doc/RELNOTES b/doc/RELNOTES index b60a233..9e29860 100644 --- a/doc/RELNOTES +++ b/doc/RELNOTES @@ -1,6 +1,62 @@ KallistiOS ##version## Copyright (C) 2002, 2003 Dan Potter -Copyright (C) 2012, 2013 Lawrence Sebald +Copyright (C) 2012-2014 Lawrence Sebald + +RELEASE NOTES for 2.0.1 +----------------------- +There are a lot less major changes in this release than in the previous one, +that is for sure. Of course, this isn't to say that there hasn't been some +interesting changes along the way. + +The first change is that all targets deprecated in 2.0.0 were removed entirely +from the tree. That is to say, there are no remnants of the GBA, PS2, or ia32 +ports of KOS in the tree anymore. If someone REALLY wants them back, please let +me know at some point and we can work that out. I doubt this will come up at +all, however. + +Further standards compliance issues were worked out for this release. KOS' core +should now compile cleanly with a relatively new GCC with the -std=c99 flag +(as well as -Wall and -Wextra). Older (prior to 4.7.x) versions of GCC might +complain about one or two things here and there, but that is not of any +particular concern. + +The fs_stat() function has been completely reworked to actually map cleanly onto +the normal C stat() function. This means you must use a struct stat when calling +the function, rather than the removed stat_t (you'll get an error if you try to +use the old struct, since it is completely gone now). If I recall correctly, the +only filesystem to actually have any direct support for fs_stat() before was +fs_vmu (which only supported it in a strange manner to get the free space left +on the VMU in question). The fs_vmu behavior has been retained so that if you do +something like fs_stat("/vmu/a1", &buf, 0), you will still get the number of +free blocks in buf.st_size (the standard doesn't say what to do with the st_size +value on a stat() call about a directory, so this is actually compliant with the +standard, oddly enough). More filesystems support fs_stat() directly now, such +as fs_dcload/fs_dclsocket. + +Hardware-wise, a new driver was added for accessing a hard drive that might be +hooked directly up to the GD-ROM port. The GD-ROM itself is actually a bit of a +strange ATA device, and it is entirely possible to chain a slave device off the +connector with a bit of a hardware modification. The new driver is in g1ata.c +(in the kernel/arch/dreamcast/hardware directory), and should work relatively +well with devices that comply with the ATA standard. The driver supports both +PIO and Multi-word DMA based access to the hard drive device, and can vastly +surpass the potential speed of the GD-ROM itself (with DMA, I get around 12.5 +megabytes per second reading sequential sectors off the drive in testing). There +have been a few small modifications to the cdrom.c file to accommodate the +possibility that a device other than the GD-ROM drive might be selected on the +bus (the BIOS syscalls do not check what device is selected). GD-ROM access is +still done through the BIOS syscalls for various reasons (including dcload ISO +redirection, which relies on the syscalls being used). The hard drive access +layer exports a kos_blockdev_t interface to interact with the drive, so you +should be able to use libkosext2fs with hard drives without any difficulties. + +The microphone driver (for the Seaman mic) has been changed around a bit. The +internal buffer has been removed in favor of a callback-based sampling approach. +The callback will be called each frame (in an IRQ handler context) while +sampling with the samples collected that frame. The idea is that you'd copy the +samples into some buffer in your program and basically return immediately from +the callback (it is called in an IRQ handler context, so you really shouldn't be +doing a lot of work in the callback). RELEASE NOTES for 2.0.0 ----------------------- @@ -28,7 +84,7 @@ The build system (including environ.sh) has seen some overhauling. You'll need to build a new environ.sh from a sample again. Additionally, your Makefile may need to change. See the examples. -The sound stream system has changed to accomidate multiple streams. Please see +The sound stream system has changed to accommodate multiple streams. Please see kernel/arch/dreamcast/include/dc/sound/* for the new info. In particular, you will need to call snd_stream_init from your program before using any of the libraries like OggVorbis. Also if you are a stream user, you need to alloc @@ -160,7 +216,7 @@ A very early port to the PS2 RTE has been added to the source tree, but will not be released as binaries (not mature enough yet). If anyone plays with this or has fixes, I'd very much like to hear from you. -The SYSCALL macro was _very_ broken, as in "I'm surprised it works" +The SYSCALL macro was _very_ broken, as in "I'm surprised it works" magnitude of broken. This may be responsible for some of the apparent breakage with newer compilers. @@ -192,7 +248,7 @@ external change is that the "more data" callback now returns not only a block of data, but the amount of data. The deprecated TA API has been removed entirely. You need to convert any -remaining code to the new PVR API or KGL. You can take a look at the +remaining code to the new PVR API or KGL. You can take a look at the examples to see how this works, but here is a quick rundown: - poly_hdr_t becomes pvr_poly_hdr_t - ta_poly_hdr_txr becomes pvr_poly_cxt_txr @@ -322,7 +378,7 @@ when the program starts. For the most part, the examples have been updated to do this. KGL has become a lot more OpenGL(tm) compliant. This means, for example, -that the usage of radians has been deprecated in favor of degrees, +that the usage of radians has been deprecated in favor of degrees, images are expected to be loaded inverted, etc. If you program which previously worked under KGL is having some issues, you should probably check to see what changed there. Paul has helpfully created a KGL manual diff --git a/kernel/arch/dreamcast/include/dc/cdrom.h b/kernel/arch/dreamcast/include/dc/cdrom.h index a033c63..daa7188 100644 --- a/kernel/arch/dreamcast/include/dc/cdrom.h +++ b/kernel/arch/dreamcast/include/dc/cdrom.h @@ -36,7 +36,7 @@ __BEGIN_DECLS /** \defgroup cd_cmd_codes CD-ROM syscall command codes These are the syscall command codes used to actually do stuff with the - GD-ROM drive. These were originally provided by thanks maiwe. + GD-ROM drive. These were originally provided by maiwe. @{ */ hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-04-20 23:30:45
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 924da83bb1acdf14e45570181d011cd3481f6e80 (commit) via ed4db90811fa7e309dd83b3846693f03c20f1fcc (commit) from fc2bc4d787a5817cc1eb79bff9125c430af2b4df (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 924da83bb1acdf14e45570181d011cd3481f6e80 Author: Lawrence Sebald <ljs...@us...> Date: Sun Apr 20 19:29:02 2014 -0400 Make fs_stat() act more like stat (and support the normal stat() function in a mostly sane way). Most filesystems in KOS never supported fs_stat() to start with, so there's not really much that anyone will have to worry about here. If you were using fs_stat() to get the number of blocks free on a VMU, make sure to fix your code. ;-) commit ed4db90811fa7e309dd83b3846693f03c20f1fcc Author: Lawrence Sebald <ljs...@us...> Date: Sun Apr 13 18:55:00 2014 -0400 Remove use of libk++ by the modplug_test example. ----------------------------------------------------------------------- Summary of changes: AUTHORS | 2 +- addons/libkosext2fs/fs_ext2.c | 160 ++++++++++++++------------ doc/CHANGELOG | 10 +- examples/dreamcast/cpp/modplug_test/Makefile | 3 +- include/kos/fs.h | 75 ++++++++----- kernel/arch/dreamcast/fs/fs_dcload.c | 38 ++++++- kernel/arch/dreamcast/fs/fs_dclsocket.c | 34 +++--- kernel/arch/dreamcast/fs/fs_vmu.c | 48 ++++---- kernel/fs/fs.c | 62 +++++++--- kernel/fs/fs_ramdisk.c | 41 +++++++- kernel/fs/fs_romdisk.c | 30 +++--- kernel/libc/newlib/newlib_stat.c | 37 +++++-- 12 files changed, 347 insertions(+), 193 deletions(-) diff --git a/AUTHORS b/AUTHORS index 7b63560..dcf916d 100644 --- a/AUTHORS +++ b/AUTHORS @@ -22,7 +22,7 @@ please see the README.KOS file in the doc directory. Contributors list (under the normal KOS license): ------------------------------------------------- Dan Potter: 1997, 2000, 2001, 2002, 2003, 2004 -Lawrence Sebald: 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 +Lawrence Sebald: 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Sam Steele: 2004 Gil Megidish: 2002 Florian Schulze: 2002 diff --git a/addons/libkosext2fs/fs_ext2.c b/addons/libkosext2fs/fs_ext2.c index 25a64e0..4c14c72 100644 --- a/addons/libkosext2fs/fs_ext2.c +++ b/addons/libkosext2fs/fs_ext2.c @@ -9,6 +9,8 @@ #include <stdint.h> #include <stdlib.h> #include <string.h> +#include <fcntl.h> +#include <limits.h> #include <sys/queue.h> #include <kos/fs.h> @@ -21,9 +23,6 @@ #include "inode.h" #include "directory.h" -/* For some reason, Newlib doesn't seem to define this function in stdlib.h. */ -extern char *realpath(const char *, const char *); - #ifdef __STRICT_ANSI__ /* These don't necessarily get prototyped in string.h in standard-compliant mode as they are extensions to the standard. Declaring them this way shouldn't @@ -1075,75 +1074,6 @@ static int fs_ext2_unlink(vfs_handler_t *vfs, const char *fn) { return 0; } -static int fs_ext2_stat(vfs_handler_t *vfs, const char *fn, stat_t *rv) { - fs_ext2_fs_t *fs = (fs_ext2_fs_t *)vfs->privdata; - int irv; - ext2_inode_t *inode; - uint32_t inode_num; - - if(!rv) { - errno = EINVAL; - return -1; - } - - mutex_lock(&ext2_mutex); - - /* Find the object in question */ - if((irv = ext2_inode_by_path(fs->fs, fn, &inode, &inode_num, 1, NULL))) { - mutex_unlock(&ext2_mutex); - errno = -irv; - return -1; - } - - /* Fill in the easy parts of the structure. */ - rv->dev = vfs; - rv->unique = inode_num; - rv->time = inode->i_mtime; - rv->attr = 0; - - /* Parse out the ext2 mode bits */ - switch(inode->i_mode & 0xF000) { - case EXT2_S_IFLNK: - rv->type = STAT_TYPE_SYMLINK; - rv->size = inode->i_size; - break; - - case EXT2_S_IFREG: - rv->type = STAT_TYPE_FILE; - rv->size = ext2_inode_size(inode); - break; - - case EXT2_S_IFDIR: - rv->type = STAT_TYPE_DIR; - rv->size = inode->i_size; - break; - - case EXT2_S_IFSOCK: - case EXT2_S_IFIFO: - case EXT2_S_IFBLK: - case EXT2_S_IFCHR: - rv->type = STAT_TYPE_PIPE; - rv->size = 0; - break; - - default: - rv->type = STAT_TYPE_NONE; - rv->size = 0; - break; - } - - /* Set the attribute bits based on the user permissions on the file. */ - if(inode->i_mode & EXT2_S_IRUSR) - rv->attr |= STAT_ATTR_R; - if(inode->i_mode & EXT2_S_IWUSR) - rv->attr |= STAT_ATTR_W; - - ext2_inode_put(inode); - mutex_unlock(&ext2_mutex); - - return 0; -} - static int fs_ext2_mkdir(vfs_handler_t *vfs, const char *fn) { fs_ext2_fs_t *fs = (fs_ext2_fs_t *)vfs->privdata; int irv; @@ -1748,6 +1678,92 @@ static ssize_t fs_ext2_readlink(vfs_handler_t *vfs, const char *path, char *buf, return len; } +int fs_ext2_stat(vfs_handler_t *vfs, const char *path, struct stat *buf, + int flag) { + + fs_ext2_fs_t *fs = (fs_ext2_fs_t *)vfs->privdata; + int irv; + ext2_inode_t *inode; + uint32_t inode_num; + int rl = 1; + uint64_t sz; + + /* Do we want the status of a symlink or of the thing it points at if we end + up with a symlink at the end of path resolution? */ + if(flag & AT_SYMLINK_NOFOLLOW) + rl = 2; + + mutex_lock(&ext2_mutex); + + /* Find the object in question */ + if((irv = ext2_inode_by_path(fs->fs, path, &inode, &inode_num, rl, NULL))) { + mutex_unlock(&ext2_mutex); + errno = -irv; + return -1; + } + + /* Fill in the structure */ + memset(buf, 0, sizeof(struct stat)); + buf->st_dev = (dev_t)((ptr_t)vfs); + buf->st_ino = inode_num; + buf->st_mode = inode->i_mode & 0x0FFF; + buf->st_nlink = inode->i_links_count; + buf->st_uid = inode->i_uid; + buf->st_gid = inode->i_gid; + + buf->st_atime = inode->i_atime; + buf->st_mtime = inode->i_mtime; + buf->st_ctime = inode->i_ctime; + buf->st_blksize = 512; + buf->st_blocks = inode->i_blocks; + + /* The rest depends on what type of inode this is... */ + switch(inode->i_mode & 0xF000) { + case EXT2_S_IFLNK: + buf->st_mode |= S_IFLNK; + buf->st_size = inode->i_size; + break; + + case EXT2_S_IFREG: + buf->st_mode |= S_IFREG; + sz = ext2_inode_size(inode); + + if(sz > LONG_MAX) { + errno = EOVERFLOW; + irv = -1; + } + + buf->st_size = sz; + break; + + case EXT2_S_IFDIR: + buf->st_mode |= S_IFDIR; + buf->st_size = inode->i_size; + break; + + case EXT2_S_IFSOCK: + buf->st_mode |= S_IFSOCK; + break; + + case EXT2_S_IFIFO: + buf->st_mode |= S_IFIFO; + break; + + case EXT2_S_IFBLK: + buf->st_mode |= S_IFBLK; + break; + + case EXT2_S_IFCHR: + buf->st_mode |= S_IFCHR; + break; + } + + ext2_inode_put(inode); + mutex_unlock(&ext2_mutex); + + return irv; +} + /* This is a template that will be used for each mount */ static vfs_handler_t vh = { /* Name Handler */ diff --git a/doc/CHANGELOG b/doc/CHANGELOG index 0259ccf..3be8523 100644 --- a/doc/CHANGELOG +++ b/doc/CHANGELOG @@ -30,6 +30,8 @@ KallistiOS version 2.0.1 ----------------------------------------------- that they can be overridden without modifying KOS [LS] - DC Corrected render-to-texture mode so that you don't have to wait for a vblank to actually render to the texture [LS] +- *** Modified fs_stat to conform (mostly) to the POSIX standard for the stat + function [LS] KallistiOS version 2.0.0 ----------------------------------------------- - DC Broadband Adapter driver fixes [Dan Potter == DP] @@ -282,7 +284,7 @@ KallistiOS version 1.2.0 ----------------------------------------------- - DC Fix for potential incorrectness in NDEBUG mode in pvr_txr_load_ex [DP] - DC Remove float usage in timer_ms_gettime() [DP] - *** More proper condvar impl using genwaits [DP] -- DC Strip trailing dots on extensionless ISO filenames (thanks waltervn for +- DC Strip trailing dots on extensionless ISO filenames (thanks waltervn for pointing this out) [DP] - *** Fix file descriptor owner bug in fdopen [Bero] - *** Zlib workaround for KOS file descriptors being non-POSIX [Bero] @@ -552,7 +554,7 @@ KallistiOS version 1.1.7 ------------------------------------------------ - DC Fixed rtc_unix_secs() [DP] - DC Added clock example [DP] - DC Added pvr_set_bg_color to glClearColor in glmisc.c [PB] -- DC Added texture wrapping enums and functionality to KGL. Cleaned up +- DC Added texture wrapping enums and functionality to KGL. Cleaned up glTexParameteri in gltex.c in the process. [PB] - DC Added texwrap example [PB] - DC Fixed some locking issues, added real date/time support to fs_vmu [DP] @@ -642,7 +644,7 @@ KallistiOS version 1.1.6 ------------------------------------------------ - DC Cleaned up cruft in DC spinlock.h [DP] - DC Pre-bundled libm.a updated to latest newlib release [DP] -* Xavier Bouchoux sent this to me earlier, but I was too lazy to get +* Xavier Bouchoux sent this to me earlier, but I was too lazy to get it integrated ^_^; KallistiOS version 1.1.5 ------------------------------------------------ @@ -845,7 +847,7 @@ KallistiOS version 0.90 ------------------------------------------------- - fs_romdisk now supports directories - Although this doesn't really affect anything in the code, the naming convention for KOS executables is now to make their extension '.klf' - instead of '.elf'. + instead of '.elf'. - Default 'zclip' in TA module is now 0.01 KallistiOS version 0.80 ------------------------------------------------- diff --git a/examples/dreamcast/cpp/modplug_test/Makefile b/examples/dreamcast/cpp/modplug_test/Makefile index 7ba2fc2..8792059 100644 --- a/examples/dreamcast/cpp/modplug_test/Makefile +++ b/examples/dreamcast/cpp/modplug_test/Makefile @@ -13,7 +13,7 @@ rm-elf: $(TARGET): $(OBJS) romdisk.o $(KOS_CCPLUS) $(KOS_CFLAGS) $(KOS_CPPFLAGS) $(KOS_LDFLAGS) -o $(TARGET) $(KOS_START) \ - $(OBJS) romdisk.o $(OBJEXTRA) -lmodplug -lk++ -lm $(KOS_LIBS) + $(OBJS) romdisk.o $(OBJEXTRA) -lmodplug -lm $(KOS_LIBS) romdisk.img: $(KOS_GENROMFS) -f romdisk.img -d romdisk -v @@ -27,4 +27,3 @@ run: $(TARGET) dist: rm -f $(OBJS) romdisk.o romdisk.img $(KOS_STRIP) $(TARGET) - diff --git a/include/kos/fs.h b/include/kos/fs.h index 6f31bfe..adadd67 100644 --- a/include/kos/fs.h +++ b/include/kos/fs.h @@ -17,6 +17,7 @@ __BEGIN_DECLS #include <time.h> #include <sys/queue.h> #include <stdarg.h> +#include <sys/stat.h> #include <kos/nmmgr.h> @@ -133,10 +134,10 @@ typedef struct vfs_handler { ssize_t (*write)(void *hnd, const void *buffer, size_t cnt); /** \brief Seek in a previously opened file */ - off_t(*seek)(void *hnd, off_t offset, int whence); + off_t (*seek)(void *hnd, off_t offset, int whence); /** \brief Return the current position in a previously opened file */ - off_t(*tell)(void *hnd); + off_t (*tell)(void *hnd); /** \brief Return the total size of a previously opened file */ size_t (*total)(void *hnd); @@ -160,8 +161,13 @@ typedef struct vfs_handler { file */ int (*complete)(void *fd, ssize_t *rv); - /** \brief Get status information on a file on the given VFS */ - int (*stat)(struct vfs_handler *vfs, const char *fn, stat_t *rv); + /** \brief Get status information on a file on the given VFS + \note path will not be passed through realpath() before calling the + filesystem-level function. It is also important to not call + realpath() in any implementation of this function as it is + possible that realpath() will call this function. */ + int (*stat)(struct vfs_handler *vfs, const char *path, struct stat *buf, + int flag); /** \brief Make a directory on the given VFS */ int (*mkdir)(struct vfs_handler *vfs, const char *fn); @@ -196,9 +202,9 @@ typedef struct vfs_handler { /** \brief Read the value of a symbolic link \note path will not be passed through realpath() before calling the - filesystem function. It is also important to not call realpath() - in your implementation as it is possible that readlink() will be - called in realpath(). */ + filesystem-level function. It is also important to not call + realpath() in any implementation of this function as it is + possible that realpath() will call this function. */ ssize_t (*readlink)(struct vfs_handler *vfs, const char *path, char *buf, size_t bufsize); } vfs_handler_t; @@ -426,37 +432,31 @@ int fs_chdir(const char *fn); up to the original length of the file, will be written back to the file when it is closed, assuming that the file is opened for writing. - Note that some of the filesystems in KallistiOS do not support this - operation. - \param hnd The descriptor to memory map. \return The memory mapped buffer, or NULL on failure. + + \note Some of the filesystems in KallistiOS do not support + this operation. If you attempt to use this function + on a filesystem that does not support it, the + function will return NULL and set errno to EINVAL. */ void *fs_mmap(file_t hnd); /** \brief Perform an I/O completion on the given file descriptor. This function is used with asynchronous I/O to perform an I/O completion on - the given file descriptor. Most filesystems do not support this operation - on KallistiOS. + the given file descriptor. \param fd The descriptor to complete I/O on. \param rv A buffer to store the size of the I/O in. \return 0 on success, -1 on failure. -*/ -int fs_complete(file_t fd, ssize_t *rv); -/** \brief Retrieve information about the specified path. - - This function retrieves the stat_t structure for the given path on the VFS. - This function is similar to the standard POSIX function stat(), but provides - slightly different data than it does. - - \param fn The path to retrieve information about. - \param rv The buffer to store stat information in. - \return 0 on success, -1 on failure. + \note Most of the filesystems in KallistiOS do not support + this operation. If you attempt to use this function + on a filesystem that does not support it, the + function will return -1 and set errno to EINVAL. */ -int fs_stat(const char *fn, stat_t *rv); +int fs_complete(file_t fd, ssize_t *rv); /** \brief Create a directory. @@ -498,10 +498,9 @@ int fs_fcntl(file_t fd, int cmd, ...); \return 0 on success, -1 on failure. \note Most filesystems in KallistiOS do not support hard - links. Unlike most other VFS functions, this one - does not set errno to ENOSYS in that case, but - rather to EMLINK to preserve existing the original - behavior in KOS. + links. If you call this function on a filesystem + that does not support hard links, the function will + return -1 and set errno to EMLINK. */ int fs_link(const char *path1, const char *path2); @@ -518,7 +517,8 @@ int fs_link(const char *path1, const char *path2); \note Most filesystems in KallistiOS do not support symbolic links. Filesystems that do not support - symlinks will simply set errno to ENOSYS. + symlinks will simply set errno to ENOSYS and return + -1. */ int fs_symlink(const char *path1, const char *path2); @@ -543,6 +543,23 @@ int fs_symlink(const char *path1, const char *path2); */ ssize_t fs_readlink(const char *path, char *buf, size_t bufsize); +/** \brief Retrieve information about the specified path. + + This function retrieves status information on the given path. This function + now returns the normal POSIX-style struct stat, rather than the old KOS + stat_t structure. In addition, you can specify whether or not this function + should resolve symbolic links on filesystems that support symlinks. + + \param path The path to retrieve information about. + \param buf The buffer to store stat information in. + \param flag Specifies whether or not to resolve a symbolic link. + If you don't want to resolve any symbolic links at + the end of the path, pass AT_SYMLINK_NOFOLLOW, + otherwise pass 0. + \return 0 on success, -1 on failure. +*/ +int fs_stat(const char *path, struct stat *buf, int flag); + /** \brief Duplicate a file descriptor. This function duplicates the specified file descriptor, returning a new file diff --git a/kernel/arch/dreamcast/fs/fs_dcload.c b/kernel/arch/dreamcast/fs/fs_dcload.c index e6d8332..55512b7 100644 --- a/kernel/arch/dreamcast/fs/fs_dcload.c +++ b/kernel/arch/dreamcast/fs/fs_dcload.c @@ -357,6 +357,42 @@ int dcload_unlink(vfs_handler_t * vfs, const char *fn) { return ret; } +static int dcload_stat(vfs_handler_t *vfs, const char *fn, struct stat *rv, + int flag) { + dcload_stat_t filestat; + int retval; + + (void)flag; + + if(lwip_dclsc && irq_inside_int()) + return 0; + + spinlock_lock(&mutex); + retval = dclsc(DCLOAD_STAT, fn, &filestat); + spinlock_unlock(&mutex); + + if(!retval) { + memset(rv, 0, sizeof(struct stat)); + rv->st_dev = (dev_t)((ptr_t)vfs); + rv->st_ino = filestat.st_ino; + rv->st_mode = filestat.st_mode; + rv->st_nlink = filestat.st_nlink; + rv->st_uid = filestat.st_uid; + rv->st_gid = filestat.st_gid; + rv->st_rdev = filestat.st_rdev; + rv->st_size = filestat.st_size; + rv->st_atime = filestat.st_atime; + rv->st_mtime = filestat.st_mtime; + rv->st_ctime = filestat.st_ctime; + rv->st_blksize = filestat.st_blksize; + rv->st_blocks = filestat.st_blocks; + + return 0; + } + + return -1; +} + static int dcload_fcntl(void *h, int cmd, va_list ap) { int rv = -1; @@ -409,7 +445,7 @@ static vfs_handler_t vh = { dcload_unlink, NULL, /* mmap */ NULL, /* complete */ - NULL, /* stat */ + dcload_stat, NULL, /* mkdir */ NULL, /* rmdir */ dcload_fcntl, diff --git a/kernel/arch/dreamcast/fs/fs_dclsocket.c b/kernel/arch/dreamcast/fs/fs_dclsocket.c index 34be302..ed620fd 100644 --- a/kernel/arch/dreamcast/fs/fs_dclsocket.c +++ b/kernel/arch/dreamcast/fs/fs_dclsocket.c @@ -565,14 +565,13 @@ static int dcls_unlink(vfs_handler_t *vfs, const char *fn) { return retval; } -static int dcls_stat(vfs_handler_t *vfs, const char *fn, stat_t *rv) { +static int dcls_stat(vfs_handler_t *vfs, const char *fn, struct stat *rv, + int flag) { command_t *cmd = (command_t *)pktbuf; dcload_stat_t filestat; int locked; - if(!rv) { - return -1; - } + (void)flag; ...<truncated>... hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-04-13 22:53:56
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via fc2bc4d787a5817cc1eb79bff9125c430af2b4df (commit) via 0c1e0abc7f4c61fd82d4ea3217f9648356b0b8a6 (commit) from f5b89be9f64977efe6643c6c3bd19c515d6d3858 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit fc2bc4d787a5817cc1eb79bff9125c430af2b4df Author: Lawrence Sebald <ljs...@us...> Date: Sun Apr 13 18:52:56 2014 -0400 Remove libk++. This probably didn't work anymore anyway, so it is gone now. Just use libstdc++ like normal targets do. commit 0c1e0abc7f4c61fd82d4ea3217f9648356b0b8a6 Author: Lawrence Sebald <ljs...@us...> Date: Sun Apr 13 18:49:22 2014 -0400 Change the texture render sample to be a bit more... interesting of an example. ----------------------------------------------------------------------- Summary of changes: Makefile | 3 - examples/dreamcast/pvr/texture_render/ta.c | 54 ++++++++++++++--------- libk++/Makefile | 20 --------- libk++/mem.cc | 63 ---------------------------- libk++/pure_virtual.c | 15 ------- 5 files changed, 33 insertions(+), 122 deletions(-) delete mode 100644 libk++/Makefile delete mode 100644 libk++/mem.cc delete mode 100644 libk++/pure_virtual.c diff --git a/Makefile b/Makefile index f552532..a46bf46 100644 --- a/Makefile +++ b/Makefile @@ -13,9 +13,6 @@ KOS_CFLAGS += -Wextra # Add stuff to DIRS to auto-compile it with the big tree. DIRS = utils -ifdef KOS_CCPLUS - DIRS += libk++ -endif DIRS += kernel addons # examples # Detect a non-working or missing environ.sh file. diff --git a/examples/dreamcast/pvr/texture_render/ta.c b/examples/dreamcast/pvr/texture_render/ta.c index 492de15..ab1b275 100644 --- a/examples/dreamcast/pvr/texture_render/ta.c +++ b/examples/dreamcast/pvr/texture_render/ta.c @@ -2,7 +2,14 @@ The big difference in this program is that we add in a small bit of user input code, and that we support render-to-texture mode. */ -#include <kos.h> +#include <stdio.h> + +#include <arch/types.h> +#include <arch/timer.h> + +#include <dc/pvr.h> +#include <dc/maple.h> +#include <dc/maple/controller.h> /* A little test program -- creates six rainbow polygons and moves them around over a white background. */ @@ -104,7 +111,7 @@ void draw_one_textured_poly(polyplace_t *p) { pvr_prim(&vert, sizeof(vert)); } -int to_texture = 0; +int to_texture = 1; pvr_ptr_t d_texture; uint32 tx_x = 1024, tx_y = 512; @@ -121,10 +128,8 @@ void draw_frame() { if(!to_texture) pvr_scene_begin(); - else { + else pvr_scene_begin_txr(d_texture, &tx_x, &tx_y); - to_texture = 2; - } pvr_list_begin(PVR_LIST_OP_POLY); @@ -142,7 +147,8 @@ void draw_frame() { pvr_scene_finish(); /* Move all polygons */ - move_polys(); + if(!to_texture) + move_polys(); } void draw_textured() { @@ -150,19 +156,17 @@ void draw_textured() { pvr_poly_hdr_t hdr; int i; - pvr_poly_cxt_txr(&cxt, PVR_LIST_OP_POLY, PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED, 1024, 512, d_texture, PVR_FILTER_NONE); + draw_frame(); + + pvr_poly_cxt_txr(&cxt, PVR_LIST_OP_POLY, + PVR_TXRFMT_RGB565 | PVR_TXRFMT_NONTWIDDLED, 1024, 512, + d_texture, PVR_FILTER_NONE); pvr_poly_compile(&hdr, &cxt); - /* Start opaque poly list */ pvr_wait_ready(); + pvr_scene_begin(); - if(to_texture == 3) { - pvr_scene_begin_txr(d_texture, &tx_x, &tx_y); - to_texture = 2; - } - else - pvr_scene_begin(); - + /* Start opaque poly list */ pvr_list_begin(PVR_LIST_OP_POLY); /* Send polygon header to the TA using store queues */ @@ -184,7 +188,8 @@ void draw_textured() { /* Main program: init and loop drawing polygons */ pvr_init_params_t pvr_params = { - { PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_0, PVR_BINSIZE_0, PVR_BINSIZE_0 }, + { PVR_BINSIZE_16, PVR_BINSIZE_0, PVR_BINSIZE_0, + PVR_BINSIZE_0, PVR_BINSIZE_0 }, 64 * 1024 }; @@ -194,6 +199,7 @@ int main(int argc, char **argv) { int finished = 0; uint64 timer = timer_ms_gettime64(), start, end; uint32 counter = 0; + pvr_stats_t stats; pvr_init(&pvr_params); @@ -224,18 +230,24 @@ int main(int argc, char **argv) { } } - if(to_texture < 2) + if(!to_texture) { draw_frame(); - else + ++counter; + } + else { draw_textured(); - - ++counter; + counter += 2; + } } end = timer_ms_gettime64(); printf("%lu frames in %llu ms = %f FPS\n", counter, end - start, - counter / ((float)end - start) * 1000.0f); + counter / ((float)end - start) * 1000.0); + + pvr_get_stats(&stats); + printf("From pvr_get_stats:\n\tVBlank Count: %lu\n\tFrame Count: %lu\n", + stats.vbl_count, stats.frame_count); pvr_mem_free(d_texture); diff --git a/libk++/Makefile b/libk++/Makefile deleted file mode 100644 index f490973..0000000 --- a/libk++/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# -# libk++ -# -# Simplified libstdc++ for KOS -# -# Makefile (c)2002 Dan Potter -# - -OBJS = mem.o pure_virtual.o -SUBDIRS = - -KOS_CPPFLAGS += $(KOS_CPPSTD) - -myall: $(OBJS) - rm -f $(KOS_BASE)/lib/$(KOS_ARCH)/libk++.a - $(KOS_AR) rcs $(KOS_BASE)/lib/$(KOS_ARCH)/libk++.a $(OBJS) - -include $(KOS_BASE)/Makefile.prefab - - diff --git a/libk++/mem.cc b/libk++/mem.cc deleted file mode 100644 index b5b2d76..0000000 --- a/libk++/mem.cc +++ /dev/null @@ -1,63 +0,0 @@ -/* KallistiOS ##version## - - libk++/mem.cc - - (c)2002 Gil Megidish -*/ - -#include <sys/cdefs.h> -#include <arch/arch.h> -#include <stdio.h> -#include <sys/types.h> - -/* This file contains definitions for the basic malloc/free operations - in C++. You can use this tiny replacement for libstdc++ when you - don't need the whole thing. */ - -extern "C" void free(void*); -extern "C" void *malloc(unsigned); - -#if defined(_arch_dreamcast) -asm( - ".text\n" - ".global __ZdlPv\n" - ".global __Znwj\n" - ".global __ZdaPv\n" - ".global __Znaj\n" - ".extern _free\n" - ".extern _malloc\n" - "__ZdlPv:\n" - "__ZdaPv:\n" - " mov.l freeaddr,r0\n" - " jmp @r0\n" - " nop\n" - ".align 2\n" - "freeaddr: .long _free\n" - "__Znwj:\n" - "__Znaj:\n" - " mov.l mallocaddr,r0\n" - " jmp @r0\n" - " nop\n" - ".align 2\n" - "mallocaddr: .long _malloc\n" -); -#endif - -/* void operator delete(void *ptr) { - if (ptr) - free(ptr); -} - -void* operator new(size_t len) { - return malloc(len); -} - - -void operator delete[](void *ptr) { - ::operator delete(ptr); -} - -void* operator new[](size_t len) { - return ::operator new(len); -} */ - diff --git a/libk++/pure_virtual.c b/libk++/pure_virtual.c deleted file mode 100644 index 494cb7a..0000000 --- a/libk++/pure_virtual.c +++ /dev/null @@ -1,15 +0,0 @@ -/* KallistiOS ##version## - - pure_virtual.c - Copyright (C)2003 Dan Potter - - Provides a libsupc++ function for using pure virtuals. Thanks to - Bero for the info. - */ - -#include <arch/arch.h> - -void __cxa_pure_virtual() { - panic("Pure virtual method called"); -} - hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-04-09 04:24:17
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via f5b89be9f64977efe6643c6c3bd19c515d6d3858 (commit) from 31688b75f341f5d0fb8606e5169b92e4f2d2d2be (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f5b89be9f64977efe6643c6c3bd19c515d6d3858 Author: Lawrence Sebald <ljs...@us...> Date: Wed Apr 9 00:22:07 2014 -0400 Attempt to use the _EXT read/write dma commands when asked to transfer > 256 sectors, unless they aren't available. This should fix most of the problems with the lack of chaining of transfers for DMA (transferring the max number of sectors by the _EXT commands would require 32MiB of ram, so we don't have to worry about chaining them). ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/hardware/g1ata.c | 36 +++++++++++++++++++++---------- 1 files changed, 24 insertions(+), 12 deletions(-) diff --git a/kernel/arch/dreamcast/hardware/g1ata.c b/kernel/arch/dreamcast/hardware/g1ata.c index a5c6830..a8862e7 100644 --- a/kernel/arch/dreamcast/hardware/g1ata.c +++ b/kernel/arch/dreamcast/hardware/g1ata.c @@ -164,6 +164,12 @@ static semaphore_t dma_done = SEM_INITIALIZER(0); #define g1_ata_wait_drdy() \ do {} while(!(IN8(G1_ATA_ALTSTATUS) & G1_ATA_SR_DRDY)) +static inline int use_lba28(uint64_t sector, size_t count) { + return ((sector + count) < 0x0FFFFFFF) && (count <= 256); +} + +#define CAN_USE_LBA48() ((device.command_sets & (1 << 26))) + static void g1_dma_irq_hnd(uint32 code) { /* XXXX: Probably should look at the code to make sure it isn't an error. */ (void)code; @@ -480,7 +486,7 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, int rv = 0; uint8_t dsel; uint32_t addr; - int old; + int old, can_lba48 = CAN_USE_LBA48(); /* Make sure we're actually being asked to do work... */ if(!count) @@ -510,7 +516,7 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, } /* Chaining isn't done yet, so make sure we don't need to. */ - if(count > 256) { + if(count > 65536 || (!can_lba48 && count > 256)) { errno = EOVERFLOW; return -1; } @@ -554,11 +560,12 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, dsel = IN8(G1_ATA_DEVICE_SELECT); /* Which mode are we using: LBA28 or LBA48? */ - if((sector + count) <= 0x0FFFFFFF) { + if(!can_lba48 || use_lba28(sector, count)) { OUT8(G1_ATA_DEVICE_SELECT, 0xF0 | ((sector >> 24) & 0x0F)); /* Write out the number of sectors we want and the lower 24-bits of - the LBA we're looking for. */ + the LBA we're looking for. Note that putting 0 into the sector count + register returns 256 sectors. */ OUT8(G1_ATA_SECTOR_COUNT, (uint8_t)count); OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); @@ -570,7 +577,9 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, else { OUT8(G1_ATA_DEVICE_SELECT, 0xF0); - /* Write out the number of sectors we want and the LBA. */ + /* Write out the number of sectors we want and the LBA. Note that in + LBA48 mode, putting 0 into the sector count register returns 65536 + sectors (not that we have that much RAM on the Dreamcast). */ OUT8(G1_ATA_SECTOR_COUNT, (uint8_t)(count >> 8)); OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 24) & 0xFF)); OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 32) & 0xFF)); @@ -678,7 +687,7 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, int rv = 0; uint8_t dsel; uint32_t addr; - int old; + int old, can_lba48 = CAN_USE_LBA48(); /* Make sure we're actually being asked to do work... */ if(!count) @@ -708,7 +717,7 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, } /* Chaining isn't done yet, so make sure we don't need to. */ - if(count > 256) { + if(count > 65536 || (!can_lba48 && count > 256)) { errno = EOVERFLOW; return -1; } @@ -723,7 +732,7 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, addr = ((uint32_t)buf) & 0x0FFFFFFF; if(addr & 0x1F) { - dbglog(DBG_ERROR, "g1_ata_write_lba_dma: Unaligned output address\n"); + dbglog(DBG_ERROR, "g1_ata_write_lba_dma: Unaligned input address\n"); errno = EFAULT; return -1; } @@ -755,11 +764,12 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, dsel = IN8(G1_ATA_DEVICE_SELECT); /* Which mode are we using: LBA28 or LBA48? */ - if((sector + count) <= 0x0FFFFFFF) { + if(!can_lba48 || use_lba28(sector, count)) { OUT8(G1_ATA_DEVICE_SELECT, 0xF0 | ((sector >> 24) & 0x0F)); - /* Write out the number of sectors we want and the lower 24-bits of - the LBA we're looking for. */ + /* Write out the number of sectors we have and the lower 24-bits of + the LBA we're looking for. Note that putting 0 into the sector count + register writes 256 sectors. */ OUT8(G1_ATA_SECTOR_COUNT, (uint8_t)count); OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); @@ -772,7 +782,9 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, else { OUT8(G1_ATA_DEVICE_SELECT, 0xF0); - /* Write out the number of sectors we want and the LBA. */ + /* Write out the number of sectors we have and the LBA. Note that in + LBA48 mode, putting 0 into the sector count register writes 65536 + sectors (not that we have that much RAM on the Dreamcast). */ OUT8(G1_ATA_SECTOR_COUNT, (uint8_t)(count >> 8)); OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 24) & 0xFF)); OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 32) & 0xFF)); hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-04-09 04:18:40
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via 31688b75f341f5d0fb8606e5169b92e4f2d2d2be (commit) from ee3cbf93da87b065e7e81a3a910fab59e098b86c (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 31688b75f341f5d0fb8606e5169b92e4f2d2d2be Author: Lawrence Sebald <ljs...@us...> Date: Wed Apr 9 00:18:13 2014 -0400 Add missing atab_write_blocks_dma() function. ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/hardware/g1ata.c | 17 +++++++++++++++++ 1 files changed, 17 insertions(+), 0 deletions(-) diff --git a/kernel/arch/dreamcast/hardware/g1ata.c b/kernel/arch/dreamcast/hardware/g1ata.c index c2f9e75..a5c6830 100644 --- a/kernel/arch/dreamcast/hardware/g1ata.c +++ b/kernel/arch/dreamcast/hardware/g1ata.c @@ -15,6 +15,7 @@ #include <kos/sem.h> #include <arch/timer.h> +#include <arch/cache.h> /* This file implements support for accessing devices over the G1 bus by the @@ -727,6 +728,9 @@ int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, return -1; } + /* Flush the dcache over the range of the data. */ + dcache_flush_range((uint32)buf, count * 512); + /* Disable IRQs temporarily... */ old = irq_disable(); @@ -997,6 +1001,19 @@ static int atab_write_blocks(kos_blockdev_t *d, uint64_t block, size_t count, (const uint16_t *)buf); } +static int atab_write_blocks_dma(kos_blockdev_t *d, uint64_t block, + size_t count, const void *buf) { + ata_devdata_t *data = (ata_devdata_t *)d->dev_data; + + if(block + count > data->end_block) { + errno = EOVERFLOW; + return -1; + } + + return g1_ata_write_lba_dma(block + data->start_block, count, + (const uint16_t *)buf, 1); +} + static int atab_read_blocks_chs(kos_blockdev_t *d, uint64_t block, size_t count, void *buf) { ata_devdata_t *data = (ata_devdata_t *)d->dev_data; hooks/post-receive -- A pseudo Operating System for the Dreamcast. |
From: Lawrence S. <ljs...@us...> - 2014-04-07 03:48:36
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via ee3cbf93da87b065e7e81a3a910fab59e098b86c (commit) from 64fcf84781df572490f455e9112017947a2f4840 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit ee3cbf93da87b065e7e81a3a910fab59e098b86c Author: Lawrence Sebald <ljs...@us...> Date: Sun Apr 6 23:48:10 2014 -0400 Add DMA write support to g1ata. ----------------------------------------------------------------------- Summary of changes: kernel/arch/dreamcast/hardware/g1ata.c | 202 ++++++++++++++++++++++++------ kernel/arch/dreamcast/include/dc/g1ata.h | 34 +++++ 2 files changed, 197 insertions(+), 39 deletions(-) diff --git a/kernel/arch/dreamcast/hardware/g1ata.c b/kernel/arch/dreamcast/hardware/g1ata.c index cea5b62..c2f9e75 100644 --- a/kernel/arch/dreamcast/hardware/g1ata.c +++ b/kernel/arch/dreamcast/hardware/g1ata.c @@ -116,7 +116,9 @@ typedef struct ata_devdata { #define ATA_CMD_READ_DMA_EXT 0x25 #define ATA_CMD_WRITE_SECTORS 0x30 #define ATA_CMD_WRITE_SECTORS_EXT 0x34 +#define ATA_CMD_WRITE_DMA_EXT 0x35 #define ATA_CMD_READ_DMA 0xC8 +#define ATA_CMD_WRITE_DMA 0xCA #define ATA_CMD_FLUSH_CACHE 0xE7 #define ATA_CMD_FLUSH_CACHE_EXT 0xEA #define ATA_CMD_IDENTIFY 0xEC @@ -135,6 +137,10 @@ typedef struct ata_devdata { /* Access timing data. */ #define G1_ACCESS_WDMA_MODE2 0x00001001 +/* DMA Settings. */ +#define G1_DMA_TO_DEVICE 0 +#define G1_DMA_TO_MEMORY 1 + /* Macros to access the ATA registers */ #define OUT32(addr, data) *((volatile uint32_t *)addr) = data #define OUT16(addr, data) *((volatile uint16_t *)addr) = data @@ -187,6 +193,44 @@ static inline int g1_ata_wait_drq(void) { return (val & (G1_ATA_SR_ERR | G1_ATA_SR_DF)) ? -1 : 0; } +static int dma_common(uint8_t cmd, size_t nsects, uint32_t addr, int dir, + int block) { + uint8_t status; + + /* Set the DMA parameters up. */ + OUT32(G1_ATA_DMA_ADDRESS, addr); + OUT32(G1_ATA_DMA_LENGTH, nsects * 512); + OUT32(G1_ATA_DMA_DIRECTION, dir); + + /* Enable G1 DMA. */ + OUT32(G1_ATA_DMA_ENABLE, 1); + + /* Wait until the drive is ready to accept the command. */ + g1_ata_wait_nbsy(); + g1_ata_wait_drdy(); + + /* Write out the command to the device. */ + OUT8(G1_ATA_COMMAND_REG, cmd); + + /* Start the DMA transfer. */ + OUT32(G1_ATA_DMA_STATUS, 1); + + if(block) { + sem_wait(&dma_done); + + /* Ack the IRQ. */ + status = IN8(G1_ATA_STATUS_REG); + + /* Was there an error doing the transfer? */ + if(status & G1_ATA_SR_ERR) { + errno = EIO; + return -1; + } + } + + return 0; +} + int g1_ata_read_chs(uint16_t c, uint8_t h, uint8_t s, size_t count, uint16_t *buf) { int rv = 0; @@ -430,42 +474,6 @@ out: return rv; } -static int dma_common(uint8_t cmd, size_t nsects, uint32_t addr, int block) { - uint8_t status; - - /* Set the DMA parameters up. */ - OUT32(G1_ATA_DMA_ADDRESS, addr); - OUT32(G1_ATA_DMA_LENGTH, nsects * 512); - OUT32(G1_ATA_DMA_DIRECTION, 1); - - /* Enable G1 DMA. */ - OUT32(G1_ATA_DMA_ENABLE, 1); - - /* Wait until the drive is ready to accept the command. */ - g1_ata_wait_nbsy(); - g1_ata_wait_drdy(); - - /* Write out the command to the device. */ - OUT8(G1_ATA_COMMAND_REG, cmd); - - /* Start the DMA transfer. */ - OUT32(G1_ATA_DMA_STATUS, 1); - - if(block) - sem_wait(&dma_done); - - /* Ack the IRQ. */ - status = IN8(G1_ATA_STATUS_REG); - - /* Was there an error doing the transfer? */ - if(status & G1_ATA_SR_ERR) { - errno = EIO; - return -1; - } - - return 0; -} - int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, int block) { int rv = 0; @@ -556,7 +564,7 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 16) & 0xFF)); /* Do the rest of the work... */ - rv = dma_common(ATA_CMD_READ_DMA, count, addr, block); + rv = dma_common(ATA_CMD_READ_DMA, count, addr, G1_DMA_TO_MEMORY, block); } else { OUT8(G1_ATA_DEVICE_SELECT, 0xF0); @@ -572,7 +580,8 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 16) & 0xFF)); /* Do the rest of the work... */ - rv = dma_common(ATA_CMD_READ_DMA_EXT, count, addr, block); + rv = dma_common(ATA_CMD_READ_DMA_EXT, count, addr, G1_DMA_TO_MEMORY, + block); } OUT8(G1_ATA_DEVICE_SELECT, dsel); @@ -663,6 +672,121 @@ int g1_ata_write_lba(uint64_t sector, size_t count, const uint16_t *buf) { return rv; } +int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, + int block) { + int rv = 0; + uint8_t dsel; + uint32_t addr; + int old; + + /* Make sure we're actually being asked to do work... */ + if(!count) + return 0; + + if(!buf) { + errno = EFAULT; + return -1; + } + + /* Make sure that we've been initialized and there's a disk attached. */ + if(!devices) { + errno = ENXIO; + return -1; + } + + /* Make sure the disk supports LBA mode. */ + if(!device.max_lba) { + errno = ENOTSUP; + return -1; + } + + /* Make sure the disk supports Multi-Word DMA mode 2. */ + if(!device.wdma_modes) { + errno = EPERM; + return -1; + } + + /* Chaining isn't done yet, so make sure we don't need to. */ + if(count > 256) { + errno = EOVERFLOW; + return -1; + } + + /* Make sure the range of sectors is valid. */ + if((sector + count) > device.max_lba) { + errno = EOVERFLOW; + return -1; + } + + /* Check the alignment of the address. */ + addr = ((uint32_t)buf) & 0x0FFFFFFF; + + if(addr & 0x1F) { + dbglog(DBG_ERROR, "g1_ata_write_lba_dma: Unaligned output address\n"); + errno = EFAULT; + return -1; + } + + /* Disable IRQs temporarily... */ + old = irq_disable(); + + /* Make sure there is no DMA in progress already. */ + if(dma_in_progress || g1_dma_in_progress()) { + irq_restore(old); + dbglog(DBG_KDEBUG, "g1_ata_write_lba_dma: DMA in progress\n"); + errno = EIO; + return -1; + } + + /* Set the settings for this transfer and reenable IRQs. */ + dma_blocking = block; + dma_in_progress = 1; + irq_restore(old); + + /* Wait for the device to signal it is ready. */ + g1_ata_wait_nbsy(); + + /* For now, just assume we're accessing the slave device. We don't care + about the primary device, since it should always be the GD-ROM drive. */ + dsel = IN8(G1_ATA_DEVICE_SELECT); + + /* Which mode are we using: LBA28 or LBA48? */ + if((sector + count) <= 0x0FFFFFFF) { + OUT8(G1_ATA_DEVICE_SELECT, 0xF0 | ((sector >> 24) & 0x0F)); + + /* Write out the number of sectors we want and the lower 24-bits of + the LBA we're looking for. */ + OUT8(G1_ATA_SECTOR_COUNT, (uint8_t)count); + OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); + OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); + OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 16) & 0xFF)); + + /* Do the rest of the work... */ + rv = dma_common(ATA_CMD_WRITE_DMA, count, addr, G1_DMA_TO_DEVICE, + block); + } + else { + OUT8(G1_ATA_DEVICE_SELECT, 0xF0); + + /* Write out the number of sectors we want and the LBA. */ + OUT8(G1_ATA_SECTOR_COUNT, (uint8_t)(count >> 8)); + OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 24) & 0xFF)); + OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 32) & 0xFF)); + OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 40) & 0xFF)); + OUT8(G1_ATA_SECTOR_COUNT, (uint8_t)count); + OUT8(G1_ATA_LBA_LOW, (uint8_t)((sector >> 0) & 0xFF)); + OUT8(G1_ATA_LBA_MID, (uint8_t)((sector >> 8) & 0xFF)); + OUT8(G1_ATA_LBA_HIGH, (uint8_t)((sector >> 16) & 0xFF)); + + /* Do the rest of the work... */ + rv = dma_common(ATA_CMD_WRITE_DMA_EXT, count, addr, G1_DMA_TO_DEVICE, + block); + } + + OUT8(G1_ATA_DEVICE_SELECT, dsel); + return rv; +} + int g1_ata_flush(void) { uint8_t dsel; @@ -941,7 +1065,7 @@ static kos_blockdev_t ata_blockdev_dma = { &atab_init, /* init */ &atab_shutdown, /* shutdown */ &atab_read_blocks_dma, /* read_blocks */ - &atab_write_blocks, /* XXXX: write_blocks */ + &atab_write_blocks_dma, /* write_blocks */ &atab_count_blocks, /* count_blocks */ &atab_flush /* flush */ }; diff --git a/kernel/arch/dreamcast/include/dc/g1ata.h b/kernel/arch/dreamcast/include/dc/g1ata.h index 8326ede..933c6f2 100644 --- a/kernel/arch/dreamcast/include/dc/g1ata.h +++ b/kernel/arch/dreamcast/include/dc/g1ata.h @@ -198,6 +198,40 @@ int g1_ata_read_lba_dma(uint64_t sector, size_t count, uint16_t *buf, */ int g1_ata_write_lba(uint64_t sector, size_t count, const uint16_t *buf); +/** \brief DMA Write disk sectors with Linear Block Addressing (LBA). + + This function writes one or more 512-byte disk blocks to the slave device + on the G1 ATA bus using LBA mode (either 28 or 48 bits, as appropriate). + This function uses DMA and optionally blocks until the data is written. + + \param sector The sector to start writing to. + \param count The number of disk sectors to write. + \param buf The data to write to the disk. This should be + (count * 512) bytes in length and must be at least + 32-byte aligned. + \param block Non-zero to block until the transfer completes. + \return 0 on success. < 0 on failure, setting errno as + appropriate. + + \note If errno is set to ENOTSUP after calling this + function, you must use the g1_ata_write_chs() + function instead. + + \note If errno is set to EPERM after calling this + function, DMA mode is not supported. You should use + a PIO transfer function like g1_ata_write_lba() + instead. + + \par Error Conditions: + \em ENXIO - ATA support not initialized or no device attached \n + \em EOVERFLOW - one or more of the requested sectors is out of the + range of the disk \n + \em ENOTSUP - LBA mode not supported by the device \n + \em EPERM - device does not support DMA +*/ +int g1_ata_write_lba_dma(uint64_t sector, size_t count, const uint16_t *buf, + int block); + /** \brief Flush the write cache on the attached disk. This function flushes the write cache on the disk attached as the slave hooks/post-receive -- A pseudo Operating System for the Dreamcast. |