github.com/mvdan/u-root-coreutils@v0.0.0-20230122170626-c2eef2898555/pkg/memio/ports_plan9.go (about)

     1  // Copyright 2012-2020 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  //go:build plan9
     6  // +build plan9
     7  
     8  package memio
     9  
    10  import (
    11  	"fmt"
    12  	"os"
    13  )
    14  
    15  const (
    16  	p9pathIOL = "#P/iol"
    17  	p9pathIOW = "#P/iow"
    18  	p9pathIOB = "#P/iob"
    19  )
    20  
    21  type Plan9Port struct {
    22  	iol ReadWriteCloser
    23  	iow ReadWriteCloser
    24  	iob ReadWriteCloser
    25  }
    26  
    27  var _ PortReadWriter = &Plan9Port{}
    28  
    29  // In reads data from the x86 port at address addr. Data must be Uint8, Uint16,
    30  // Uint32, but not Uint64.
    31  func (p *Plan9Port) In(addr uint16, data UintN) error {
    32  	switch data.(type) {
    33  	case *Uint32:
    34  		return p.iol.Read(data, int64(addr))
    35  	case *Uint16:
    36  		return p.iow.Read(data, int64(addr))
    37  	case *Uint8:
    38  		return p.iob.Read(data, int64(addr))
    39  	}
    40  	return fmt.Errorf("port data must be 8, 16 or 32 bits")
    41  }
    42  
    43  // Out writes data to the x86 port at address addr. data must be Uint8, Uint16
    44  // uint32, but not Uint64.
    45  func (p *Plan9Port) Out(addr uint16, data UintN) error {
    46  	switch data.(type) {
    47  	case *Uint32:
    48  		return p.iol.Write(data, int64(addr))
    49  	case *Uint16:
    50  		return p.iow.Write(data, int64(addr))
    51  	case *Uint8:
    52  		return p.iob.Write(data, int64(addr))
    53  	}
    54  	return fmt.Errorf("port data must be 8, 16 or 32 bits")
    55  }
    56  
    57  func (p *Plan9Port) Close() error {
    58  	if err := p.iol.Close(); err != nil {
    59  		return err
    60  	}
    61  	if err := p.iow.Close(); err != nil {
    62  		return err
    63  	}
    64  	return p.iob.Close()
    65  }
    66  
    67  func NewPort() (*Plan9Port, error) {
    68  	f1, err := os.OpenFile(p9pathIOL, os.O_RDWR, 0)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	f2, err := os.OpenFile(p9pathIOW, os.O_RDWR, 0)
    73  	if err != nil {
    74  		return nil, err
    75  	}
    76  	f3, err := os.OpenFile(p9pathIOB, os.O_RDWR, 0)
    77  	if err != nil {
    78  		return nil, err
    79  	}
    80  	return &Plan9Port{
    81  		iol: NewMemIOPort(f1),
    82  		iow: NewMemIOPort(f2),
    83  		iob: NewMemIOPort(f3),
    84  	}, nil
    85  }